laser_data_cairo.c
Go to the documentation of this file.
1 
2 #include <string.h>
3 
4 #include <cairo-pdf.h>
5 #include <stdlib.h>
6 #include <limits.h>
7 
8 #include "laser_data_cairo.h"
9 
10 const char* cat(const char*a, const char*b);
11 void cr_ld_draw_rays(cairo_t*, LDP);
12 void cr_ld_draw_countour(cairo_t*, LDP, double, double);
13 void cr_ld_draw_points(cairo_t*, LDP, double radius);
14 void cr_ld_draw_normals(cairo_t*cr, LDP ld, double length);
15 
16 
17 
18 /* ----------------------------------------------- */
19 
20 void cr_ld_draw_corr(cairo_t*cr, LDP laser_ref, LDP laser_sens) {
21  int i;
22  for(i=0; i < laser_sens->nrays; i++) {
23  if(!ld_valid_corr(laser_sens, i)) continue;
24 
25  if(!laser_sens->corr[i].valid) continue;
26 
27  int j1 = laser_sens->corr[i].j1;
28  int j2 = laser_sens->corr[i].j2;
29 
30  const double *p_j1 = laser_ref->points[j1].p;
31  const double *p_j2 = laser_ref->points[j2].p;
32  const double *p_i_w = laser_sens->points_w[i].p;
33  double proj[2];
34 
35  if(laser_sens->corr[i].type == corr_pl)
36  projection_on_line_d(p_j1, p_j2, p_i_w, proj, 0);
37  else
38  projection_on_segment_d(p_j1, p_j2, p_i_w, proj);
39 
40  cairo_move_to(cr, p_i_w[0], p_i_w[1]);
41  cairo_line_to(cr, proj[0], proj[1]);
42  cairo_stroke(cr);
43  }
44 }
45 
46 const char* cat(const char*a, const char*b) {
47  size_t la = strlen(a);
48  size_t lb = strlen(b);
49  char* buf = malloc(la+lb+3);
50  strcpy(buf, a);
51  strcpy(buf+la, b);
52  return buf;
53 }
54 
56  const char*prefix, const char*desc_prefix)
57 {
58  options_int(ops, cat(prefix, "draw"), &(ls->draw),
59  ls->draw, cat(desc_prefix, "Whether to draw it (0,1)"));
60 
61  options_string(ops, cat(prefix, "color"), &(ls->color),
62  ls->color, cat(desc_prefix, "Color ('red', '#f00')"));
63 
64  options_double(ops, cat(prefix, "width"), &(ls->width),
65  ls->width, cat(desc_prefix, "line width (meters)"));
66 
67 }
68 
69 
70 void lds_add_options(ld_style*lds, struct option*ops,
71  const char*prefix, const char*desc_prefix)
72 {
73  ls_add_options(&(lds->rays), ops, cat(prefix, "rays_"), cat(desc_prefix, "Rays | "));
74  ls_add_options(&(lds->countour), ops, cat(prefix, "countour_"), cat(desc_prefix, "Countour | "));
75  ls_add_options(&(lds->points), ops, cat(prefix, "points_"), cat(desc_prefix, "Points | "));
76 
77  options_double(ops, cat(prefix, "points_radius"), &(lds->points_radius),
78  lds->points_radius, cat(desc_prefix, "Point radius"));
79 
80 
81  ls_add_options(&(lds->pose), ops, cat(prefix, "pose_"), cat(desc_prefix, "PoseMarker | "));
82 
83  options_double(ops, cat(prefix, "pose_radius"), &(lds->pose_radius),
84  lds->pose_radius, cat(desc_prefix, "Point radius"));
85 
86  ls_add_options(&(lds->normals), ops, cat(prefix, "normals_"), cat(desc_prefix, "Normals | "));
87 
88  options_double(ops, cat(prefix, "normals_length"), &(lds->normals_length),
89  lds->normals_length, cat(desc_prefix, "Length of normals sticks (meters)"));
90 
91  ls_add_options(&(lds->sigma), ops, cat(prefix, "sigma_"), cat(desc_prefix, "Sigma | "));
92 
93  options_double(ops, cat(prefix, "sigma_multiplier"), &(lds->sigma_multiplier),
94  lds->sigma_multiplier, cat(desc_prefix, "Multiplier for sigma"));
95 
96 
97  options_double(ops, cat(prefix, "connect_threshold"), &(lds->connect_threshold),
98  lds->connect_threshold, cat(desc_prefix, "Threshold under which points are connected (m)."));
99  options_double(ops, cat(prefix, "horizon"), &(lds->horizon),
100  lds->horizon, cat(desc_prefix, "Maximum distance to plot (m)."));
101 }
102 
103 void cr_set_color(cairo_t *cr, const char* color) {
104  if(strlen(color) == 4 && color[0] == '#') {
105  char buf[2] = {0, 0};
106  double rgb[3];
107  int i; for(i=0;i<3;i++) {
108  buf[0] = color[1+i];
109  char* endptr;
110  rgb[i] = (1/15.0) * strtol(buf, &endptr, 16);
111  if(endptr == buf) {
112  sm_error("Unknown color component: %s.\n", buf);
113  }
114  }
115  cairo_set_source_rgb (cr, rgb[0], rgb[1], rgb[2]);
116  } else if(strlen(color) == 5 && color[0] == '#') {
117  char buf[2] = {0, 0};
118  double rgba[4];
119  int i; for(i=0;i<4;i++) {
120  buf[0] = color[1+i];
121  char* endptr;
122  rgba[i] = (1/15.0) * strtol(buf, &endptr, 16);
123  if(endptr == buf) {
124  sm_error("Unknown color component: %s.\n", buf);
125  }
126  }
127  cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
128  } else {
129  if(!strcmp(color, "black")) {
130  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
131  } else {
132  sm_error("Unknown color: %s.\n", color);
133  cairo_set_source_rgb (cr, 0.0, 1.0, 1.0);
134  }
135  }
136 }
137 
138 void cr_set_style(cairo_t *cr, line_style *ls) {
139  cr_set_color(cr, ls->color);
140  cairo_set_line_width(cr, ls->width);
141 }
142 
143 void cr_lda_draw_pose_path(cairo_t*cr, LDP*scans, int nscans, ld_reference use_reference) {
144  int k; int first_pose=1;
145  for(k=0;k<nscans;k++) {
146  LDP ld = scans[k];
147  double *pose = ld_get_reference_pose(ld, use_reference);
148  if(!pose) {
149  sm_error("No '%s' pose specified for scan #%d, continuing.\n",
150  ld_reference_to_string(use_reference));
151  continue;
152  }
153 
154  if(first_pose) {
155  first_pose = 0;
156  cairo_move_to(cr, pose[0], pose[1]);
157  } else {
158  cairo_line_to(cr, pose[0], pose[1]);
159  }
160  }
161  cairo_stroke(cr);
162 }
163 
164 
165 
166 void cr_ld_draw_rays(cairo_t*cr, LDP ld) {
167  int i; for(i=0;i<ld->nrays;i++) {
168  if(!ld_valid_ray(ld, i)) continue;
169 
170  double threshold = 0.03;
171 
172 /* if(ld->readings[i]<2) continue;*/
173 
174  double x1 = threshold * cos(ld->theta[i]);
175  double y1 = threshold * sin(ld->theta[i]);
176  double x2 = ld->readings[i] * cos(ld->theta[i]);
177  double y2 = ld->readings[i] * sin(ld->theta[i]);
178 
179  cairo_move_to(cr,x1,y1);
180  cairo_line_to(cr,x2,y2);
181  cairo_stroke(cr);
182  }
183 }
184 
185 void cr_ld_draw_countour(cairo_t*cr, LDP ld, double horizon, double connect_threshold) {
186  struct stroke_sequence draw_info[ld->nrays];
187  compute_stroke_sequence(ld, draw_info, horizon, connect_threshold);
188 
189  /* draw contour: begin_new_stroke and end_stroke tell
190  when to interrupt the stroke */
191  int i;
192  for(i=0;i<ld->nrays;i++) {
193 
194  if(draw_info[i].valid==0) continue;
195 
196  double *p = draw_info[i].p;
197 
198  if(draw_info[i].begin_new_stroke)
199  cairo_move_to(cr, p[0], p[1]);
200  else
201  cairo_line_to(cr, p[0], p[1]);
202 /* if(draw_info[i].end_stroke)*/
203  }
204  cairo_stroke(cr);
205 }
206 
207 void cr_ld_draw_points(cairo_t*cr, LDP ld, double radius) {
208  int i; for(i=0;i<ld->nrays;i++) {
209  if(!ld_valid_ray(ld, i)) continue;
210 
211  double x = ld->readings[i] * cos(ld->theta[i]);
212  double y = ld->readings[i] * sin(ld->theta[i]);
213 
214  cairo_arc (cr, x, y, radius, 0.0, 2*M_PI);
215  cairo_fill(cr);
216  }
217 }
218 
219 void cr_ld_draw_normals(cairo_t*cr, LDP ld, double length) {
220  int i; for(i=0;i<ld->nrays;i++) {
221  if(!ld_valid_ray(ld, i) || !ld_valid_alpha(ld, i)) continue;
222 
223  double alpha = ld->alpha[i];
224  double x1 = ld->readings[i] * cos(ld->theta[i]);
225  double y1 = ld->readings[i] * sin(ld->theta[i]);
226  double x2 = x1 + cos(alpha) * length;
227  double y2 = y1 + sin(alpha) * length;
228 
229  cairo_move_to(cr, x1, y1);
230  cairo_line_to(cr, x2, y2);
231  }
232  cairo_stroke (cr);
233 }
234 
235 void cr_ld_draw_sigma(cairo_t*cr, LDP ld, double multiplier) {
236  int i; for(i=0;i<ld->nrays;i++) {
237  if(!ld_valid_ray(ld, i) || is_nan(ld->readings_sigma[i])) continue;
238 
239  double theta = ld->theta[i];
240  double length = ld->readings_sigma[i] * multiplier;
241 
242  double x0 = ld->readings[i] * cos(theta);
243  double y0 = ld->readings[i] * sin(theta);
244  double x1 = x0 + cos(theta) * length;
245  double y1 = y0 + sin(theta) * length;
246  double x2 = x0 - cos(theta) * length;
247  double y2 = y0 - sin(theta) * length;
248 
249  cairo_move_to(cr, x1, y1);
250  cairo_line_to(cr, x2, y2);
251  }
252  cairo_stroke (cr);
253 }
254 
255 
256 void cr_ld_draw(cairo_t* cr, LDP ld, ld_style *p) {
257  if(p->rays.draw) {
258  cr_set_style(cr, &(p->rays));
259  cr_ld_draw_rays(cr, ld);
260  }
261 
262  if(p->countour.draw) {
263  cr_set_style(cr, &(p->countour));
265  }
266 
267  if(p->points.draw) {
268  cr_set_style(cr, &(p->points));
269  cr_ld_draw_points(cr, ld, p->points_radius);
270  }
271 
272  if(p->normals.draw) {
273  cr_set_style(cr, &(p->normals));
275  }
276 
277  if(p->sigma.draw) {
278  cr_set_style(cr, &(p->sigma));
280  }
281 
282  if(p->pose.draw) {
283  cr_set_style(cr, &(p->pose));
284  cairo_move_to(cr, 0.0, 0.0);
285  cairo_arc (cr, 0.0, 0.0, p->pose_radius, 0.0, 2*M_PI);
286  cairo_fill (cr);
287  }
288 }
289 
290 void cr_set_reference(cairo_t*cr, double*pose) {
291  cairo_translate(cr,pose[0],pose[1]);
292  cairo_rotate(cr,pose[2]);
293 }
294 
296  ls->draw = 1;
297  ls->color = "black";
298  ls->width = 0.002;
299 }
300 
302  ls_set_defaults(&(lds->rays));
303  lds->rays.color = "#f00";
304  lds->rays.width = 0.0002;
305 
306  ls_set_defaults(&(lds->countour));
307  ls_set_defaults(&(lds->points));
308  lds->points_radius = 0.003;
309  lds->points.color = "#f00";
310 
311  ls_set_defaults(&(lds->pose));
312  lds->pose.color = "#f73";
313  lds->pose_radius = 0.24;
314 
315  lds->normals_length = 0.10;
316  ls_set_defaults(&(lds->normals));
317 
318  lds->sigma_multiplier = 3;
319  ls_set_defaults(&(lds->sigma));
320  lds->sigma.draw = 0;
321 
322  lds->connect_threshold = 0.20;
323  lds->horizon = 10;
324 }
325 
326 int create_pdf_surface(const char*file, int max_width_points, int max_height_points,
327  double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr) {
328  double bb_width = bb_max[0] - bb_min[0], bb_height = bb_max[1] - bb_min[1];
329 
330 
331  double surface_width, surface_height;
332  if( bb_width > bb_height ) {
333  /* largo e basso */
334  surface_width = max_width_points;
335  surface_height = (surface_width / bb_width) * bb_height;
336  } else {
337  /* stretto e alto */
338  surface_height = max_height_points;
339  surface_width = (surface_height / bb_height) * bb_width;
340  }
341 
342  sm_debug("bb: %f %f\n", bb_width, bb_height);
343  sm_debug("surface: %f %f\n", surface_width, surface_height);
344 
345  *surface_p = cairo_pdf_surface_create(file, surface_width, surface_height);
346  *cr = cairo_create (*surface_p);
347  cairo_status_t status = cairo_status (*cr);
348 
349  if (status) {
350  sm_error("Failed to create pdf surface for file %s: %s\n",
351  file, cairo_status_to_string (status));
352  return 0;
353  }
354 
355  double world_to_surface = surface_width / bb_width;
356  cairo_scale(*cr, world_to_surface, -world_to_surface );
357  cairo_translate(*cr, -bb_min[0], -bb_max[1]);
358 
359  return 1;
360 }
361 
362 int create_image_surface(int max_width_pixels, int max_height_pixels,
363  double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr) {
364  double bb_width = bb_max[0] - bb_min[0], bb_height = bb_max[1] - bb_min[1];
365 
366  double surface_width, surface_height;
367  if( bb_width > bb_height ) {
368  /* largo e basso */
369  surface_width = max_width_pixels;
370  surface_height = (surface_width / bb_width) * bb_height;
371  } else {
372  /* stretto e alto */
373  surface_height = max_height_pixels;
374  surface_width = (surface_height / bb_height) * bb_width;
375  }
376 
377  sm_debug("bb: %f %f\n", bb_width, bb_height);
378  sm_debug("surface: %f %f\n", surface_width, surface_height);
379 
380  *surface_p = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int) surface_width, (int)surface_height);
381  *cr = cairo_create (*surface_p);
382  cairo_status_t status = cairo_status (*cr);
383 
384  if (status) {
385  sm_error("Failed to create image surface: %s\n",
386  cairo_status_to_string (status));
387  return 0;
388  }
389 
390  double world_to_surface = surface_width / bb_width;
391  cairo_scale(*cr, world_to_surface, -world_to_surface );
392  cairo_translate(*cr, -bb_min[0], -bb_max[1]);
393 
394  return 1;
395 }
396 
397 
void cr_ld_draw_corr(cairo_t *cr, LDP laser_ref, LDP laser_sens)
double horizon
line_style points
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 cr_lda_draw_pose_path(cairo_t *cr, LDP *scans, int nscans, ld_reference use_reference)
void lds_add_options(ld_style *lds, struct option *ops, const char *prefix, const char *desc_prefix)
double pose_radius
double connect_threshold
line_style countour
double *restrict readings_sigma
Definition: laser_data.h:32
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)
const char * ld_reference_to_string(ld_reference r)
double points_radius
void compute_stroke_sequence(LDP ld, struct stroke_sequence *draw_info, double horizon, double connect_threshold)
INLINE int ld_valid_corr(LDP ld, int i)
double *restrict theta
Definition: laser_data.h:21
line_style rays
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)
ld_reference
enum correspondence::@5 type
const char * color
struct option * ops
Definition: rb_sm.c:31
double sigma_multiplier
#define M_PI
Definition: math_utils.h:7
INLINE int ld_valid_alpha(LDP ld, int i)
void cr_ld_draw_points(cairo_t *, LDP, double radius)
void cr_set_reference(cairo_t *cr, double *pose)
void cr_ld_draw_normals(cairo_t *cr, LDP ld, double length)
Definition: options.h:49
double * ld_get_reference_pose(LDP ld, ld_reference use_reference)
void cr_set_color(cairo_t *cr, const char *color)
double *restrict readings
Definition: laser_data.h:24
line_style normals
line_style sigma
void cr_ld_draw(cairo_t *cr, LDP ld, ld_style *p)
const char * cat(const char *a, const char *b)
void cr_ld_draw_rays(cairo_t *, LDP)
struct @0 p
void options_int(struct option *, const char *name, int *p, int def_value, const char *desc)
const char * prefix
Definition: hsm_test00.c:17
point2d *restrict points_w
Definition: laser_data.h:47
void projection_on_line_d(const double a[2], const double b[2], const double p[2], double res[2], double *distance)
Definition: math_utils.c:135
double normals_length
struct correspondence *restrict corr
Definition: laser_data.h:36
void ls_set_defaults(line_style *ls)
int is_nan(double v)
Definition: math_utils.c:60
int create_image_surface(int max_width_pixels, int max_height_pixels, double bb_min[2], double bb_max[2], cairo_surface_t **surface_p, cairo_t **cr)
void sm_debug(const char *msg,...)
Definition: logging.c:88
void cr_ld_draw_countour(cairo_t *, LDP, double, double)
void cr_ld_draw_sigma(cairo_t *cr, LDP ld, double multiplier)
void options_string(struct option *, const char *name, const char **p, const char *def_balue, const char *desc)
void projection_on_segment_d(const double a[2], const double b[2], const double x[2], double proj[2])
Definition: math_utils.c:156
void cr_set_style(cairo_t *cr, line_style *ls)
double *restrict alpha
Definition: laser_data.h:28
void sm_error(const char *msg,...)
Definition: logging.c:49
line_style pose
void lds_set_defaults(ld_style *lds)
char buf[100]
Definition: ld_recover.c:87
double p[2]
Definition: laser_data.h:12


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