ld/ld_config/src/main.cc
Go to the documentation of this file.
1 
23 #include <string>
24 #include <iostream>
25 #include <signal.h>
26 #include <stdlib.h>
27 #include <sicktoolbox/SickLD.hh>
28 #include <stdlib.h>
29 #include "ConfigFile.h"
30 
31 #define INVALID_OPTION_STRING " Invalid option!!! :o("
32 #define PROMPT_STRING "ld?> "
33 
34 /* Config file parameters */
35 #define CONFIG_OPT_MOTOR_SPD_STR "SICK_LD_MOTOR_SPEED"
36 #define CONFIG_OPT_SCAN_AREA_STR "SICK_LD_SCAN_AREAS"
37 #define CONFIG_OPT_SCAN_RES_STR "SICK_LD_SCAN_RESOLUTION"
38 
39 using namespace std;
40 using namespace SickToolbox;
41 
47 void sigintHandler(int signal);
48 
55 int getUserOption(bool &is_null_input);
56 
62 string getFilename();
63 
69 void setConfig();
70 
75 void printConfig();
76 
95 bool parseScanAreasStr(string& scan_areas_str, double *start_angs, double *stop_angs, int& num_sectors);
96 
105 bool parseNumStr(const string& entry, double& num);
106 
107 /* A pointer to the current driver instance */
108 SickLD *sick_ld = NULL;
109 
110 int main(int argc, char* argv[])
111 {
112 
113  string sick_ip_addr(DEFAULT_SICK_IP_ADDRESS); // IP address of the Sick LD unit
114 
115  /* Check the num args */
116  if(argc > 2 || (argc == 2 && strcasecmp(argv[1],"--help") == 0)) {
117  cerr << "Usage: ld_config [SICK IP ADDRESS]" << endl
118  << "Ex. ld_config 192.168.1.11" << endl;
119  return -1;
120  }
121 
122  /* Assign the IP address */
123  if(argc == 2) {
124  sick_ip_addr = argv[1];
125  }
126 
127  /* Instantiate the SickLD driver */
128  sick_ld = new SickLD(sick_ip_addr);
129 
130  cout << endl;
131  cout << "The Sick LIDAR C++/Matlab Toolbox " << endl;
132  cout << "Sick LD Config Utility " << endl;
133  cout << endl;
134 
135  /* Initialize the Sick LD */
136  try {
137  sick_ld->Initialize();
138  }
139 
140  catch(...) {
141  cerr << "Initialize failed! Are you using the correct IP address?" << endl;
142  return -1;
143  }
144 
145  /* Register the signal handler */
146  signal(SIGINT,sigintHandler);
147 
148  do {
149 
150  cout << "Enter your choice: (Ctrl-c to exit)" << endl;
151  cout << " [1] Set new configuration"<< endl;
152  cout << " [2] Show current settings"<< endl;
153  cout << PROMPT_STRING;
154 
155  bool is_null_input;
156  switch(getUserOption(is_null_input)) {
157 
158  case 1:
159  setConfig();
160  break;
161  case 2:
162  printConfig();
163  break;
164  default:
165  if(!is_null_input) {
166  cerr << INVALID_OPTION_STRING << endl;
167  }
168 
169  }
170 
171  cout << endl;
172 
173  } while(true);
174 
175  /* Success */
176  return 0;
177 
178 }
179 
183 void sigintHandler(int signal) {
184 
185  cout << endl;
186  cout << "Quitting..." << endl;
187 
188  /* Unitialize the device */
189  try {
190 
191  sick_ld->Uninitialize();
192  delete sick_ld;
193 
194  }
195 
196  catch(...) {
197  cerr << "Uninitialize failed!" << endl;
198  exit(-1);
199  }
200 
201  cout << endl;
202  cout << "Thanks for using the Sick LIDAR Matlab/C++ Toolbox!" << endl;
203  cout << "Bye Bye :o)" << endl;
204 
205  exit(0);
206 
207 }
208 
212 int getUserOption(bool &is_null_input) {
213 
214  string user_input_str;
215  getline(cin,user_input_str);
216 
217  // Check whether its null input
218  is_null_input = true;
219  if (user_input_str.length() > 0) {
220  is_null_input = false;
221  }
222 
223  int int_val = 0;
224  istringstream input_stream(user_input_str);
225  input_stream >> int_val;
226 
227  return int_val;
228 
229 }
230 
234 string getFilename() {
235 
236  string filename;
237 
238  cout << "config file: ";
239  getline(cin,filename);
240 
241  return filename;
242 
243 }
244 
248 void setConfig() {
249 
250  int motor_spd;
251  int num_sectors;
252  double scan_res;
253  double start_angs[SickLD::SICK_MAX_NUM_MEASURING_SECTORS] = {0};
254  double stop_angs[SickLD::SICK_MAX_NUM_MEASURING_SECTORS] = {0};
255  string scan_areas_str;
256 
257  ConfigFile sick_config_file; // Extracts values from config file
258  string config_path;
259 
260  /* Prompt the user for the filename */
261  config_path = getFilename();
262 
263  /* Instantiate the parser */
264  if(ifstream(config_path.c_str())) {
265  sick_config_file = ConfigFile(config_path);
266  }
267  else {
268  cerr << "Invalid filename!" << endl;
269  return;
270  }
271 
272  /* Use the ConfigFile class to extract the various parameters for
273  * the sick configuration.
274  *
275  * NOTE: The third parameter specifies the value to use, if the second
276  * parameter is not found in the file.
277  */
278  if(!sick_config_file.readInto(motor_spd,CONFIG_OPT_MOTOR_SPD_STR)) {
279  cerr << "ERROR: Invalid config file - " << CONFIG_OPT_MOTOR_SPD_STR << " needs to be specified!" << endl;
280  return;
281  }
282 
283  if(!sick_config_file.readInto(scan_res,CONFIG_OPT_SCAN_RES_STR)) {
284  cerr << "ERROR: Invalid config file - " << CONFIG_OPT_SCAN_RES_STR << " needs to be specified!" << endl;
285  return;
286  }
287 
288  if(!sick_config_file.readInto(scan_areas_str,CONFIG_OPT_SCAN_AREA_STR)) {
289  cerr << "ERROR: Invalid config file - " << CONFIG_OPT_SCAN_AREA_STR << " needs to be specified!" << endl;
290  return;
291  }
292 
293  /* Extract the start/stop pairs and angle res for the scanning sectors */
294  if (!parseScanAreasStr(scan_areas_str,start_angs,stop_angs,num_sectors)) {
295  cerr << "ERROR: Parser failed to extract scan areas!" << endl;
296  return;
297  }
298 
299  /* Set the global parameters - we pass them all at once to ensure a feasible config */
300  cout << endl << "\tAttempting to configure the Sick LD..." << endl;
301 
302  try {
303  sick_ld->SetSickGlobalParamsAndScanAreas(motor_spd,scan_res,start_angs,stop_angs,num_sectors);
304  }
305 
306  catch(SickConfigException &sick_config_exception) {
307  cerr << "ERROR: Couldn't set requested configuration!" << endl;
308  return;
309  }
310 
311  catch(...) {
312  exit(-1);
313  }
314 
315  cout << "\t\tConfiguration Successfull!!!" << endl;
316 
317 }
318 
322 void printConfig() {
323 
324  cout << endl;
325  sick_ld->PrintSickStatus();
326  sick_ld->PrintSickIdentity();
327  sick_ld->PrintSickGlobalConfig();
328  sick_ld->PrintSickEthernetConfig();
329  sick_ld->PrintSickSectorConfig();
330 
331 }
332 
336 bool parseScanAreasStr(string& areas, double * start_angs, double * stop_angs, int& num_pairs) {
337 
338  unsigned long i; // number of sectors found so far
339  unsigned int start_pos = 0; // starting position of a sector in 'areas'
340  unsigned int end_pos = 0; // ending position of a sector in 'areas'
341  unsigned int split = 0; // position of the delimiter inside a sector
342  string pair; // a string of 'areas' that contains one start and one stop angle
343 
344  /* Get the beginning and end of the first scan sector */
345  start_pos = areas.find('[',start_pos); // Find the next [, starting at start_pos
346  end_pos = areas.find(']',start_pos);
347 
348  /* Keep getting sectors until we either run out of open
349  * brackets or we exceed the number of allowed sectors
350  */
351  for(i=0; (start_pos != (unsigned int)string::npos) && (i <= SickLD::SICK_MAX_NUM_MEASURING_SECTORS); i++) {
352 
353  pair = areas.substr(start_pos+1,end_pos-(start_pos+1));
354 
355  /* Eliminate any padding before first value */
356  try {
357  pair = pair.substr(pair.find_first_not_of(' '));
358  }
359 
360  catch(...) {
361  cerr << "ERROR: There was an problem parsing your scan areas! Check your config file." << endl;
362  return false;
363  }
364 
365  split = pair.find(' ');
366 
367  /* Catch a lack of ' ' inside the sector definition;
368  * alternative is to let it fail at pair.substr(split)
369  */
370  if(split == (unsigned int)string::npos) {
371  cerr << "ERROR: Invalid sector definition." << endl;
372  return false;
373  }
374 
375  /* Get the number from the beginning to the delimiter */
376  if(!parseNumStr(pair.substr(0,split),start_angs[i])) {
377  cerr << "ERROR: Invalid start angle found." << endl;
378  return false;
379  }
380 
381  /* Get the number from the delimiter to the end */
382  if(!parseNumStr(pair.substr(split),stop_angs[i])) {
383  cerr << "ERROR: Invalid stop angle found." << endl;
384  return false;
385  }
386 
387  start_pos = end_pos; // Shift to the end of the current sector
388 
389  /* Try to find another sector */
390  start_pos = areas.find("[", start_pos);
391  end_pos = areas.find("]", start_pos);
392 
393  }
394 
395  num_pairs = i;
396 
397  /* Check if we broke out because of too many loops */
398  if(num_pairs > SickLD::SICK_MAX_NUM_MEASURING_SECTORS) {
399  cerr << "ERROR: Too many scan areas found (max " << SickLD::SICK_MAX_NUM_MEASURING_SECTORS << ")" << endl;
400  return false;
401  }
402 
403  /* Or, we might not have even entered the loop */
404  if(num_pairs == 0) {
405  cerr << "ERROR: No scan areas found! Check brackets in your config file." << endl;
406  return false;
407  }
408 
409  /* Success! */
410  return true;
411 
412 }
413 
417 bool parseNumStr(const string& entry, double& num)
418 {
419 
420  string num_str = entry.substr(entry.find_first_not_of(' '));
421  istringstream input_stream(num_str.c_str());
422  if(!(input_stream >> num)) {
423  cerr << "ERROR: Invalid angle value: " + num_str << endl;
424  return false;
425  }
426 
427  /* Success! */
428  return true;
429 
430 }
void printConfig()
Prints the current Sick status/config.
string getFilename()
Prompts the user for config filename.
void PrintSickGlobalConfig() const
Print the Sick LD&#39;s global configuration.
Definition: SickLD.cc:1638
Provides a simple driver interface for working with the Sick LD-OEM/Sick LD-LRS long-range models via...
Definition: SickLD.hh:56
void PrintSickSectorConfig() const
Print the Sick LD&#39;s sector configuration.
Definition: SickLD.cc:1652
#define CONFIG_OPT_SCAN_RES_STR
bool parseScanAreasStr(string &scan_areas_str, double *start_angs, double *stop_angs, int &num_sectors)
void setConfig()
Attempts to set the desired config via the driver. Parses configuration file as well.
#define INVALID_OPTION_STRING
bool parseNumStr(const string &entry, double &num)
void sigintHandler(int signal)
int main(int argc, char *argv[])
void SetSickGlobalParamsAndScanAreas(const unsigned int sick_motor_speed, const double sick_step_angle, const double *const active_sector_start_angles, const double *const active_sector_stop_angles, const unsigned int num_active_sectors)
Attempts to set the scan resolution and active sectors/scan areas for the device (in flash) ...
Definition: SickLD.cc:1140
#define DEFAULT_SICK_IP_ADDRESS
Default Sick LD INet 4 address.
Definition: SickLD.hh:21
#define CONFIG_OPT_SCAN_AREA_STR
void PrintSickStatus() const
Print the status of the Sick LD.
Definition: SickLD.cc:1624
void Initialize()
Initializes the driver and syncs it with Sick LD unit. Uses sector config given in flash...
Definition: SickLD.cc:91
void PrintSickEthernetConfig() const
Print the Sick LD&#39;s Ethernet configuration.
Definition: SickLD.cc:1645
Defines the SickLD class for working with the Sick LD-OEM/LD-LRS long range LIDARs.
Encapsulates the Sick LIDAR Matlab/C++ toolbox.
Definition: SickLD.cc:44
SickLD * sick_ld
bool readInto(T &var, const string &key) const
Definition: ConfigFile.h:195
void PrintSickIdentity() const
Print the parameters comprising the Sick LD&#39;s identity.
Definition: SickLD.cc:1631
void Uninitialize()
Tear down the connection between the host and the Sick LD.
Definition: SickLD.cc:1659
#define CONFIG_OPT_MOTOR_SPD_STR
Thrown when the driver detects (or the Sick reports) an invalid config.
int getUserOption(bool &is_null_input)
#define PROMPT_STRING


sicktoolbox
Author(s): Jason Derenick , Thomas Miller
autogenerated on Tue Sep 10 2019 03:37:34