sm1.c
Go to the documentation of this file.
1 #include <time.h>
2 #include <string.h>
3 
4 #include "../csm/csm_all.h"
5 
6 #include <options/options.h>
7 
8 struct sm1_params {
9  const char * file1;
10  const char * file2;
11  const char * file_jj;
12  const char * file_output;
13  int debug;
14 
15  int algo;
17 } p;
18 
19 
20 extern int distance_counter;
21 extern void sm_options(struct sm_params*p, struct option*ops);
22 
23 
24 const char *sm1_banner =
25 
26 "There are TWO ways to define the input to this program.\n"
27 " \n"
28 "Say that in file A there are the scans \n"
29 " \n"
30 " A1 A2 A3 A4 ... \n"
31 " \n"
32 "and in file B there are the scans \n"
33 " \n"
34 " B1 B2 B3 B4 ... \n"
35 " \n"
36 "With this command line: \n"
37 " \n"
38 " sm1 --file1 A --file2 B \n"
39 " \n"
40 "the matchings will be: \n"
41 " \n"
42 " (A1, B1), (A2, B2), etc.\n"
43 " \n"
44 "While with this command line:\n"
45 " \n"
46 " sm1 --file1 A --file2 A\n"
47 " \n"
48 "the matchings will be \n"
49 " \n"
50 " (A1, A2), (A3, A4), (A5, A6), ... \n"
51 " \n";
52 
53 
54 int main(int argc, const char*argv[]) {
55  sm_set_program_name(argv[0]);
57 
58  struct sm_params params;
59  struct sm_result result;
60 
61  struct option* ops = options_allocate(100);
62  options_string(ops, "file1", &p.file1, "file1.txt",
63  "File with first series of scans (at pose1)");
64  options_string(ops, "file2", &p.file2, "file2.txt",
65  "File with second series of scans (at pose2)");
66  options_string(ops, "file_jj", &p.file_jj, "",
67  "File for journaling -- if left empty, journal not open.");
68  options_string(ops, "out", &p.file_output, "stdout", "Output file (JSON structs)");
69  options_int(ops, "algo", &p.algo, 0, "Which algorithm to use (0:(pl)ICP 1:gpm-stripped 2:HSM) ");
70 
71  options_int(ops, "debug", &p.debug, 0, "Shows debug information");
72  options_int(ops, "write_post_mortem", &p.write_post_mortem, 1, "In case of failure, writes a post mortem.");
73 
74  sm_options(&params, ops);
75  if(!options_parse_args(ops, argc, argv)) {
76  fprintf(stderr, "\n\nUsage:\n");
77  options_print_help(ops, stderr);
78  return -1;
79  }
80 
82 
84  FILE * file2 = !strcmp(p.file1, p.file2) ? file1
86  if(!file1 || !file2) return -1;
87 
88  FILE * out = open_file_for_writing(p.file_output);
89  if(!out) return -2;
90 
91  if(strcmp(p.file_jj, "")) {
92  FILE * jj = open_file_for_writing(p.file_jj);
93  if(!jj) return -1;
94  jj_set_stream(jj);
95  }
96 
97  LDP ld1, ld2;
98  int count = 0;
99  while(1) {
100  count++;
101 
102  ld1 = ld_from_json_stream(file1);
103  if(!ld1) {
104  if(feof(file1)) break;
105  sm_error("Invalid data in file1 '%s' \n", p.file1);
106  return 2;
107  }
108  ld2 = ld_from_json_stream(file2);
109  if(!ld2) {
110  if(feof(file2)) break;
111  sm_error("Invalid data in file2 '%s' \n", p.file2);
112  return 3;
113  }
114 
115  params.laser_ref = ld1;
116  params.laser_sens = ld2;
117 
118  if( any_nan(params.laser_ref->odometry,3) ||
119  any_nan(params.laser_sens->odometry,3) ) {
120  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");
121  sm_error(" (file %s) laser_ref->odometry = %s \n", p.file1, friendly_pose(params.laser_ref->odometry) );
122  sm_error(" (file %s) laser_sens->odometry = %s \n", p.file2, friendly_pose(params.laser_sens->odometry) );
123  sm_error(" I will quit it here. \n");
124  return 3;
125  }
126 
127  pose_diff_d( params.laser_sens->odometry,
128  /* o minus */ params.laser_ref->odometry,
129  /* = */ params.first_guess);
130 
131  /* Do the actual work */
132  switch(p.algo) {
133  case(0):
134  sm_icp(&params, &result); break;
135  case(1):
136  sm_gpm(&params, &result); break;
137  case(2):
138  sm_hsm(&params, &result); break;
139  default:
140  sm_error("Unknown algorithm to run: %d.\n",p.algo);
141  return -1;
142  }
143 
144  if(p.write_post_mortem && !result.valid) {
145  char casename[256];
146  sprintf(casename, "sm1_failure_matching%d", count);
147  sm_error("sm1: matching #%d failed. Writing a special case %s.\n", count, casename );
148 // save_testcase(&params)
149 
150  char file_config[256],file1[256],file2[256],file_jj[256],script[256];
151 
152  sprintf(file_config, "%s.config", casename);
153  sprintf(file1, "%s_laser_ref.json", casename);
154  sprintf(file2, "%s_laser_sens.json", casename);
155  sprintf(file_jj, "%s.journal", casename);
156  sprintf(script, "%s.sh", casename);
157 
158  FILE * f = fopen(file_config, "w");
159  options_dump(ops,f,0);
160  fclose(f);
161 
162  f = fopen(file1, "w");
163  ld_write_as_json(params.laser_ref,f);
164  fclose(f);
165 
166  f = fopen(file2, "w");
167  ld_write_as_json(params.laser_sens,f);
168  fclose(f);
169 
170  f = fopen(script, "w");
171  fprintf(f, "#!/bin/bash\n");
172  fprintf(f, "%s -config %s -file1 %s -file2 %s -debug 1 -file_jj %s -write_post_mortem 0 \n",
173  argv[0], file_config, file1, file2, file_jj);
174  fprintf(f, "sm_animate -in %s -out %s_anim.pdf \n", file_jj, casename);
175  fclose(f);
176  }
177 
178 
179  JO jo = result_to_json(&params, &result);
180 
181  double true_x[3];
183  params.laser_ref->true_pose, true_x);
184  double true_e[3];
185 
186  pose_diff_d(result.x, true_x, true_e);
187  /* int i=0;for(;i<3;i++) true_e[i] = result.x[i] - true_x[i];*/
188 
189  jo_add_double_array(jo, "true_x", true_x, 3);
190  jo_add_double_array(jo, "true_e", true_e, 3);
191 
192  fputs(json_object_to_json_string(jo), out);
193  fputs("\n",out);
194 
195  jo_free(jo);
196  ld_free(ld1);
197  ld_free(ld2);
198  }
199 
200  fclose(file1);
201  if(file2 != file1) fclose(file2);
202  fclose(out);
203 
204 
205  return 0;
206 }
void options_banner(const char *message)
Definition: options.c:33
double true_pose[3]
Definition: laser_data.h:38
void sm_set_program_name(const char *name)
Definition: logging.c:21
const char * file2
Definition: sm1.c:10
void sm_icp(struct sm_params *input, struct sm_result *output)
Definition: icp.c:29
const char * file1
Definition: sm1.c:9
const char * file_output
Definition: sm1.c:12
void ld_write_as_json(LDP ld, FILE *stream)
double odometry[3]
Definition: laser_data.h:39
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
void sm_options(struct sm_params *p, struct option *ops)
Definition: sm_options.c:6
int algo
Definition: sm1.c:15
struct option * ops
Definition: rb_sm.c:31
FILE * open_file_for_writing(const char *filename)
Definition: utils.c:25
const char * sm1_banner
Definition: sm1.c:24
int valid
Definition: algos.h:140
void options_dump(struct option *options, FILE *f, int write_desc)
Definition: options.c:332
Definition: options.h:49
void ld_free(LDP ld)
Definition: laser_data.c:87
int distance_counter
Definition: math_utils.c:46
int write_post_mortem
Definition: sm1.c:16
JO result_to_json(struct sm_params *p, struct sm_result *r)
struct option * options_allocate(int n)
LDP ld_from_json_stream(FILE *file)
const char * json_object_to_json_string(struct json_object *this)
Definition: json_object.c:199
void options_int(struct option *, const char *name, int *p, int def_value, const char *desc)
LDP laser_ref
Definition: algos.h:14
void sm_debug_write(int flag)
Definition: logging.c:16
LDP laser_sens
Definition: algos.h:16
void jo_add_double_array(JO root, const char *name, const double *v, int n)
FILE * open_file_for_reading(const char *filename)
Definition: utils.c:19
const char * file_jj
Definition: sm1.c:11
double first_guess[3]
Definition: algos.h:19
void options_print_help(struct option *options, FILE *f)
Definition: options.c:398
double x[3]
Definition: algos.h:143
struct sm1_params p
int debug
Definition: sm1.c:13
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
int main(int argc, const char *argv[])
Definition: sm1.c:54
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
Definition: sm1.c:8
#define jo_free


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