sm_animate.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <string.h>
3 #include <float.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 
7 #include <cairo-pdf.h>
8 
9 #include <options/options.h>
10 
11 #include "../csm/csm_all.h"
12 #include "../csm/laser_data_drawing.h"
13 #include "../csm/laser_data_cairo.h"
14 
15 typedef struct {
16  const char * file_input;
17 
18  const char * file_output;
19 
20  ld_style laser_ref_s, laser_sens_s;
21  /* Drawing style for correspondences */
23 
24 
25  double max_width_cm;
26  double max_height_cm;
27 
29  int zoom_ray;
30 
31  /* maximum size, in points, of the output pdf */
32  int width_pt, height_pt;
33 
34  /* Padding, in meters, to be added */
35  double padding;
36 
38 } anim_params ;
39 
40 int draw_animation( anim_params* p, JO jo, const char*filename);
42 
43 
44 int main(int argc, const char** argv)
45 {
46  sm_set_program_name(argv[0]);
47 
48  anim_params p;
49  set_defaults(&p);
50 
51  struct option* ops = options_allocate(100);
52  options_string(ops, "in", &p.file_input, "stdin", "Input file (defaults to stdin)");
53  options_string(ops, "out", &p.file_output, "sm_animate_%02d.pdf", "Output file ");
54 
55  options_int(ops, "write_info", &p.write_info, 0, "Writes informations and statistics in the picture.");
56  options_int(ops, "max_iterations", &p.max_iterations, 10, "Maximum number of iterations");
57  options_int(ops, "zoom_ray", &p.zoom_ray, -1, "If >= 0, the action is zoomed on a particular ray.");
58  options_int(ops, "width_pt", &p.width_pt, 500, "Maximum width, in points, of the PDF.");
59  options_int(ops, "height_pt", &p.height_pt, 500, "Maximum height, in points, of the PDF.");
60  options_double(ops, "padding", &p.padding, 0.2, "Padding, in meters, to be added around figure.");
61 
62  lds_add_options(&(p.laser_ref_s), ops, "ref_", "");
63  lds_add_options(&(p.laser_sens_s), ops, "sens_", "");
64  ls_add_options(&(p.corr), ops, "corr_", "");
65 
66  if(!options_parse_args(ops, argc, argv)) {
67  sm_info("Draws ICP animation. It reads the output created by sm2 when given the 'file_jj' switch. \n\nUsage:\n");
68  options_print_help(ops, stderr);
69  return -1;
70  }
71 
72  FILE * input = open_file_for_reading(p.file_input);
73  if(!input) return -1;
74 
75  JO jo; int count = 0;
76  while( (jo = json_read_stream(input)) ) {
77  char filename[100];
78  sprintf(filename, p.file_output, count);
79  sm_info("Writing frame %s \n", p.file_output);
80  if(!draw_animation(&p, jo, filename))
81  return -2;
82  count++;
83  }
84 
85  return 0;
86 }
87 
89 int draw_animation(anim_params* p, JO jo, const char*filename) {
90  JO jo_ref = jo_get(jo, "laser_ref");
91  JO jo_sens = jo_get(jo, "laser_sens");
92  if(!jo_ref || !jo_sens) {
93  sm_error("Could not get laser_ref/laser_sens.\n");
94  return 0;
95  }
96 
97  LDP laser_ref = json_to_ld(jo_ref);
98  LDP laser_sens = json_to_ld(jo_sens);
99  if(!laser_ref || !laser_sens) {
100  sm_error("Could not read laser_ref/laser_sens from JSON representation.\n");
101  return 0;
102  }
103 
104  ld_compute_cartesian(laser_ref);
105  ld_compute_cartesian(laser_sens);
106 
107  double ld_min[2], ld_max[2];
108  if(p->zoom_ray == -1) {
109  double zero[3] = {0,0,0};
110  if(!ld_get_bounding_box(laser_ref, ld_min, ld_max, zero, p->laser_ref_s.horizon)){
111  sm_error("Not enough good points to establish bounding box.\n");
112  return 0;
113  }
114  } else {
115  if(p->zoom_ray < 0 || p->zoom_ray >= laser_ref->nrays || !ld_valid_ray(laser_ref, p->zoom_ray)) {
116  sm_error("Ray index #%d is not valid in laser_ref.\n", p->zoom_ray);
117  return 0;
118  }
119 
120  ld_min[0] = ld_max[0] = laser_ref->points[p->zoom_ray].p[0];
121  ld_min[1] = ld_max[1] = laser_ref->points[p->zoom_ray].p[1];
122  }
123 
124  ld_min[0] -= p->padding;
125  ld_min[1] -= p->padding;
126  ld_max[0] += p->padding;
127  ld_max[1] += p->padding;
128 
129  sm_info("Bounding box: %f %f -- %f %f\n", ld_min[0], ld_min[1], ld_max[0], ld_max[1]);
130 
131  cairo_surface_t *surface;
132  cairo_t *cr;
133 
134  if(!create_pdf_surface(filename, p->width_pt, p->height_pt,
135  ld_min, ld_max, &surface, &cr)) return 0;
136 
137  JO iterations = jo_get(jo, "iterations");
138  if(!iterations || !json_object_is_type(iterations, json_type_array)) {
139  fprintf(stderr, "Could not read iterations.\n");
140  return 0;
141  }
142 
143  int niterations = json_object_array_length(iterations);
144  if(niterations>p->max_iterations) niterations = p->max_iterations;
145  sm_info("Displaying %d iterations.\n", niterations);
146 
147  int it;
148  for(it=0;it<niterations;it++) {
149  JO iteration = json_object_array_get_idx(iterations, it);
150 
151  double x_old[3], x_new[3];
152  jo_read_double_array(iteration, "x_old", x_old, 3, NAN);
153  jo_read_double_array(iteration, "x_new", x_new, 3, NAN);
154 
155 
156  cairo_save(cr);
157  cr_ld_draw(cr, laser_ref, &(p->laser_ref_s));
158 
159  ld_compute_world_coords(laser_sens, x_old);
160 
161 
162  JO corr0 = jo_get(iteration, "corr0");
163  JO corr1 = jo_get(iteration, "corr1");
164  JO corr2 = jo_get(iteration, "corr2");
165  if(!corr1 || !corr2 || !corr0) {
166  sm_error("Iteration %d: could not read correspondences (field 'corr<i>'). Probably ICP failed here?\n", it);
167  } else {
168  cr_set_style(cr, &(p->corr));
169  cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
170  json_to_corr(corr0, laser_sens->corr, laser_sens->nrays);
171  cr_ld_draw_corr(cr, laser_ref, laser_sens);
172 
173  cairo_set_source_rgb (cr, 1.0, 0.0, 1.0);
174  json_to_corr(corr1, laser_sens->corr, laser_sens->nrays);
175  cr_ld_draw_corr(cr, laser_ref, laser_sens);
176 
177  cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
178  json_to_corr(corr2, laser_sens->corr, laser_sens->nrays);
179  cr_ld_draw_corr(cr, laser_ref, laser_sens);
180  }
181 
182  cr_set_reference(cr, x_old);
183  cr_ld_draw(cr, laser_sens, &(p->laser_sens_s));
184 
185  cairo_restore(cr);
186 
187  if(p->write_info) {
188  cairo_save(cr);
189  cairo_identity_matrix(cr);
190  cairo_set_font_size (cr, 20.0f);
191  cairo_select_font_face (cr, "Sans",
192  CAIRO_FONT_SLANT_NORMAL,
193  CAIRO_FONT_WEIGHT_NORMAL);
194 
195  char text[100];
196  sprintf(text, "Iteration #%d: x_old: %s", it, friendly_pose(x_old));
197  cairo_move_to(cr, 0.0, -20.0 );
198  cairo_show_text(cr, text);
199 
200  sm_info("%s\n",text);
201  cairo_restore(cr);
202  }
203 
204  cairo_show_page (cr);
205  }
206 
207  ld_free(laser_ref);
208  ld_free(laser_sens);
209 
210  cairo_destroy (cr);
211  cairo_surface_destroy (surface);
212 
213  return 1;
214 }
215 
216 
220  ls_set_defaults(&(p->corr));
221  p->laser_ref_s.points.color = "#00f";
222  p->laser_sens_s.points.color = "#f00";
226  p->laser_ref_s.pose_radius = 0.015;
227 
228 }
229 
void cr_ld_draw_corr(cairo_t *cr, LDP laser_ref, LDP laser_sens)
int json_object_array_length(struct json_object *this)
Definition: json_object.c:516
double horizon
int width_pt
Definition: sm_animate.c:32
line_style points
ld_style laser_ref_s
Definition: sm_animate.c:20
void sm_set_program_name(const char *name)
Definition: logging.c:21
point2d *restrict points
Definition: laser_data.h:44
void ls_add_options(line_style *ls, struct option *ops, const char *prefix, const char *desc_prefix)
void lds_add_options(ld_style *lds, struct option *ops, const char *prefix, const char *desc_prefix)
#define NAN
Definition: math_utils.h:11
LDP json_to_ld(JO jo)
double pose_radius
int json_object_is_type(struct json_object *this, int type)
Definition: json_object.c:184
line_style corr
Definition: sm_animate.c:22
int create_pdf_surface(const char *file, int max_width_points, int max_height_points, double bb_min[2], double bb_max[2], cairo_surface_t **surface_p, cairo_t **cr)
int write_info
Definition: sm_animate.c:37
const char * friendly_pose(const double *pose)
Definition: math_utils.c:266
INLINE int ld_valid_ray(LDP ld, int i)
void options_double(struct option *, const char *name, double *p, double def_value, const char *desc)
const char * color
struct option * ops
Definition: rb_sm.c:31
void cr_set_reference(cairo_t *cr, double *pose)
void set_defaults(anim_params *p)
Definition: sm_animate.c:217
Definition: options.h:49
void ld_free(LDP ld)
Definition: laser_data.c:87
double padding
Definition: sm_animate.c:35
void cr_ld_draw(cairo_t *cr, LDP ld, ld_style *p)
struct option * options_allocate(int n)
struct @0 p
const char * file_output
Definition: sm_animate.c:18
void options_int(struct option *, const char *name, int *p, int def_value, const char *desc)
int jo_read_double_array(JO s, const char *name, double *p, int n, double when_null)
FILE * open_file_for_reading(const char *filename)
Definition: utils.c:19
struct correspondence *restrict corr
Definition: laser_data.h:36
const char * file_input
Definition: sm_animate.c:16
#define jo_get
void ld_compute_world_coords(LDP ld, const double *pose)
Definition: laser_data.c:133
void options_print_help(struct option *options, FILE *f)
Definition: options.c:398
void ls_set_defaults(line_style *ls)
ld_style laser_sens_s
Definition: sm_animate.c:20
double max_width_cm
Definition: sm_animate.c:25
double max_height_cm
Definition: sm_animate.c:26
void sm_info(const char *msg,...)
Definition: logging.c:71
int main(int argc, const char **argv)
Definition: sm_animate.c:44
void options_string(struct option *, const char *name, const char **p, const char *def_balue, const char *desc)
int json_to_corr(JO array, struct correspondence *corr, int n)
int zoom_ray
Definition: sm_animate.c:29
int height_pt
Definition: sm_animate.c:32
JO json_read_stream(FILE *f)
void ld_compute_cartesian(LDP ld)
Definition: laser_data.c:118
void cr_set_style(cairo_t *cr, line_style *ls)
struct json_object * json_object_array_get_idx(struct json_object *this, int idx)
Definition: json_object.c:535
int max_iterations
Definition: sm_animate.c:28
void sm_error(const char *msg,...)
Definition: logging.c:49
int draw_animation(anim_params *p, JO jo, const char *filename)
Definition: sm_animate.c:89
line_style pose
void lds_set_defaults(ld_style *lds)
int options_parse_args(struct option *ops, int argc, const char *argv[])
Definition: options.c:66
int ld_get_bounding_box(LDP ld, double bb_min[2], double bb_max[2], double pose[3], double horizon)
double p[2]
Definition: laser_data.h:12


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