sm2.c
Go to the documentation of this file.
1 #include <time.h>
2 #include <string.h>
3 #include <libgen.h>
4 
5 #include <options/options.h>
6 #include "../csm/csm_all.h"
7 
8 struct {
9  const char * file_in;
10  const char * file_out;
11  const char * file_out_stats;
12  const char * file_jj;
13  int format;
14 
15  /* which algorithm to run */
16  int algo;
17 
19 
20  int debug;
21 } p;
22 
23 extern void sm_options(struct sm_params*p, struct option*ops);
24 
25 void spit(LDP ld, FILE * stream);
26 
27 int main(int argc, const char*argv[]) {
28  sm_set_program_name(argv[0]);
29 
30  struct sm_params params;
31  struct sm_result result;
32 
33  struct option* ops = options_allocate(100);
34  options_string(ops, "in", &p.file_in, "stdin", "Input file ");
35  options_string(ops, "out", &p.file_out, "stdout", "Output file ");
36  options_string(ops, "out_stats", &p.file_out_stats, "", "Output file (stats) ");
37  options_string(ops, "file_jj", &p.file_jj, "",
38  "File for journaling -- if left empty, journal not open.");
39  options_int(ops, "algo", &p.algo, 0, "Which algorithm to use (0:(pl)ICP 1:gpm-stripped 2:HSM) ");
40 
41  options_int(ops, "debug", &p.debug, 0, "Shows debug information");
42  options_int(ops, "recover_from_error", &p.recover_from_error, 0, "If true, tries to recover from an ICP matching error");
43 
44 
45  p.format = 0;
46 /* options_int(ops, "format", &p.format, 0,
47  "Output format (0: log in JSON format, 1: log in Carmen format (not implemented))");*/
48 
49  sm_options(&params, ops);
50  if(!options_parse_args(ops, argc, argv)) {
51  fprintf(stderr, "\n\nUsage:\n");
52  options_print_help(ops, stderr);
53  return -1;
54  }
55 
56  sm_debug_write(p.debug);
57 
58  /* Open input and output files */
59 
60  FILE * file_in = open_file_for_reading(p.file_in);
61  if(!file_in) return -1;
62  FILE * file_out = open_file_for_writing(p.file_out);
63  if(!file_out) return -1;
64 
65  if(strcmp(p.file_jj, "")) {
66  FILE * jj = open_file_for_writing(p.file_jj);
67  if(!jj) return -1;
68  jj_set_stream(jj);
69  }
70 
71  FILE * file_out_stats = 0;
72  if(strcmp(p.file_out_stats, "")) {
73  file_out_stats = open_file_for_writing(p.file_out_stats);
74  if(!file_out_stats) return -1;
75  }
76 
77  /* Read first scan */
78  LDP laser_ref;
79  if(!(laser_ref = ld_read_smart(file_in))) {
80  sm_error("Could not read first scan.\n");
81  return -1;
82  }
83  if(!ld_valid_fields(laser_ref)) {
84  sm_error("Invalid laser data in first scan.\n");
85  return -2;
86  }
87 
88 
89  /* For the first scan, set estimate = odometry */
90  copy_d(laser_ref->odometry, 3, laser_ref->estimate);
91 
92  spit(laser_ref, file_out);
93  int count=-1;
94  LDP laser_sens;
95  while( (laser_sens = ld_read_smart(file_in)) ) {
96 
97  count++;
98  if(!ld_valid_fields(laser_sens)) {
99  sm_error("Invalid laser data in (#%d in file).\n", count);
100  return -(count+2);
101  }
102 
103  params.laser_ref = laser_ref;
104  params.laser_sens = laser_sens;
105 
106  /* Set first guess as the difference in odometry */
107 
108  if( any_nan(params.laser_ref->odometry,3) ||
109  any_nan(params.laser_sens->odometry,3) ) {
110  sm_error("The 'odometry' field is set to NaN so I don't know how to get an initial guess. I usually use the difference in the odometry fields to obtain the initial guess.\n");
111  sm_error(" laser_ref->odometry = %s \n", friendly_pose(params.laser_ref->odometry) );
112  sm_error(" laser_sens->odometry = %s \n", friendly_pose(params.laser_sens->odometry) );
113  sm_error(" I will quit it here. \n");
114  return -3;
115  }
116 
117  double odometry[3];
118  pose_diff_d(laser_sens->odometry, laser_ref->odometry, odometry);
119  double ominus_laser[3], temp[3];
120  ominus_d(params.laser, ominus_laser);
121  oplus_d(ominus_laser, odometry, temp);
122  oplus_d(temp, params.laser, params.first_guess);
123 
124  /* Do the actual work */
125  switch(p.algo) {
126  case(0):
127  sm_icp(&params, &result); break;
128  case(1):
129  sm_gpm(&params, &result); break;
130  case(2):
131  sm_hsm(&params, &result); break;
132  default:
133  sm_error("Unknown algorithm to run: %d.\n",p.algo);
134  return -1;
135  }
136 
137  if(!result.valid){
138  if(p.recover_from_error) {
139  sm_info("One ICP matching failed. Because you passed -recover_from_error, I will try to recover."
140  " Note, however, that this might not be good in some cases. \n");
141  sm_info("The recover is that the displacement is set to 0. No result stats is output. \n");
142 
143  /* For the first scan, set estimate = odometry */
144  copy_d(laser_ref->estimate, 3, laser_sens->estimate);
145 
146  ld_free(laser_ref); laser_ref = laser_sens;
147 
148  } else {
149  sm_error("One ICP matching failed. Because I process recursively, I will stop here.\n");
150  sm_error("Use the option -recover_from_error if you want to try to recover.\n");
151  ld_free(laser_ref);
152  return 2;
153  }
154  } else {
155 
156  /* Add the result to the previous estimate */
157  oplus_d(laser_ref->estimate, result.x, laser_sens->estimate);
158 
159  /* Write the corrected log */
160  spit(laser_sens, file_out);
161 
162  /* Write the statistics (if required) */
163  if(file_out_stats) {
164  JO jo = result_to_json(&params, &result);
165  fputs(jo_to_string(jo), file_out_stats);
166  fputs("\n", file_out_stats);
167  jo_free(jo);
168  }
169 
170  ld_free(laser_ref); laser_ref = laser_sens;
171  }
172  }
173  ld_free(laser_ref);
174 
175  return 0;
176 }
177 
178 
179 void spit(LDP ld, FILE * stream) {
180  switch(p.format) {
181  case(0): {
182  ld_write_as_json(ld, stream);
183  break;
184  }
185  case(1): {
186  /* XXX: to implement */
187  break;
188  }
189  }
190 }
void sm_set_program_name(const char *name)
Definition: logging.c:21
const char * file_in
Definition: sm2.c:9
void sm_icp(struct sm_params *input, struct sm_result *output)
Definition: icp.c:29
#define jo_to_string
void ld_write_as_json(LDP ld, FILE *stream)
double odometry[3]
Definition: laser_data.h:39
void copy_d(const double *from, int n, double *to)
Definition: math_utils.c:83
const char * file_out
Definition: sm2.c:10
void sm_hsm(struct sm_params *input, struct sm_result *output)
Definition: hsm_interface.c:56
const char * friendly_pose(const double *pose)
Definition: math_utils.c:266
int ld_valid_fields(LDP ld)
Definition: laser_data.c:179
void sm_options(struct sm_params *p, struct option *ops)
Definition: sm_options.c:6
struct option * ops
Definition: rb_sm.c:31
struct @3 p
FILE * open_file_for_writing(const char *filename)
Definition: utils.c:25
int format
Definition: sm2.c:13
int valid
Definition: algos.h:140
LDP ld_read_smart(FILE *)
Definition: options.h:49
void ld_free(LDP ld)
Definition: laser_data.c:87
int algo
Definition: sm2.c:16
JO result_to_json(struct sm_params *p, struct sm_result *r)
struct option * options_allocate(int n)
void options_int(struct option *, const char *name, int *p, int def_value, const char *desc)
const char * file_jj
Definition: sm2.c:12
int main(int argc, const char *argv[])
Definition: sm2.c:27
LDP laser_ref
Definition: algos.h:14
void sm_debug_write(int flag)
Definition: logging.c:16
void spit(LDP ld, FILE *stream)
Definition: sm2.c:179
int debug
Definition: sm2.c:20
LDP laser_sens
Definition: algos.h:16
FILE * open_file_for_reading(const char *filename)
Definition: utils.c:19
double first_guess[3]
Definition: algos.h:19
void oplus_d(const double x1[3], const double x2[3], double res[3])
Definition: math_utils.c:96
double laser[3]
Definition: algos.h:121
void options_print_help(struct option *options, FILE *f)
Definition: options.c:398
void ominus_d(const double x[3], double res[3])
Definition: math_utils.c:87
double estimate[3]
Definition: laser_data.h:40
double x[3]
Definition: algos.h:143
const char * file_out_stats
Definition: sm2.c:11
void sm_info(const char *msg,...)
Definition: logging.c:71
int any_nan(const double *d, int n)
Definition: math_utils.c:64
void options_string(struct option *, const char *name, const char **p, const char *def_balue, const char *desc)
void pose_diff_d(const double pose2[3], const double pose1[3], double res[3])
Definition: math_utils.c:115
void sm_error(const char *msg,...)
Definition: logging.c:49
void sm_gpm(struct sm_params *input, struct sm_result *output)
Definition: gpm.c:11
void jj_set_stream(FILE *f)
Definition: json_journal.c:109
int options_parse_args(struct option *ops, int argc, const char *argv[])
Definition: options.c:66
int recover_from_error
Definition: sm2.c:18
#define jo_free


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23