laser_data_carmen.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <math.h>
3 #include <ctype.h>
4 
5 #include "csm_all.h"
6 
7 const char * carmen_prefix = "FLASER ";
8 
10 int read_next_double(const char*line, size_t*cur, double*d);
11 
13 int read_next_integer(const char*line, size_t*cur, int*d);
14 
16 int read_next_string(const char*line, size_t*cur, char*buf, size_t buf_len);
17 
18 
20 int read_next_double(const char*line, size_t*cur, double*d) {
21  int inc;
22  int ret = sscanf(line+*cur, " %lf %n", d, &inc);
23  if(1 != ret) {
24  sm_error("Could not read double at %p + %d '%s'. ret: %d.\n", line, *cur, line+*cur, ret);
25  return -1;
26  }
27  *cur += inc;
28  return 0;
29 }
30 
32 int read_next_integer(const char*line, size_t*cur, int*d) {
33  int inc;
34  if(1 != sscanf(line+*cur, " %d %n", d, &inc)) {
35  /* sm_error("Could not read integer.\n");*/
36  return -1;
37  }
38  *cur += inc;
39  return 0;
40 }
41 
43 int read_next_string(const char*line, size_t*cur, char*buf, size_t buf_len) {
44  int from = *cur; while(isspace(line[from])) from++;
45  size_t len = 0; while(!isspace(line[from+len])) len++;
46  if(len > buf_len ) len = buf_len;
47  strncpy(buf, line+from, len);
48  *cur += len;
49  return 0;
50 }
51 
52 LDP ld_from_carmen_string(const char*line) {
53 
54  if(0 != strncmp(line, carmen_prefix, strlen(carmen_prefix))) {
55  sm_error("This is not a Carmen line: \n-> %s\n", line);
56  return 0;
57  }
58 
59  size_t cur = strlen(carmen_prefix);
60 
61 
62  int nrays=-1;
63  if(read_next_integer(line, &cur, &nrays)) {
64  sm_error("Could not get number of rays.\n");
65  goto error;
66  }
67 
68  LDP ld = ld_alloc_new(nrays);
69 
70 
71  double fov = M_PI;
72  double min_reading = 0;
73  double max_reading = 80;
74 
75  if(nrays == 769) {
76  min_reading = 0.001;
77  max_reading = 4;
78  fov = deg2rad(270.0);
79 
80  static int print = 0;
81  if(!print) { print = 1;
82  sm_info("Assuming that 769 rays is an Hokuyo "
83  "with fov = %f deg, min_reading = %f m, max_reading = %fm\n",
84  rad2deg(fov), min_reading, max_reading);
85  }
86  }
87 
88  ld->min_theta = -fov/2;
89  ld->max_theta = +fov/2;
90 
91  int on_error = 0;
92  int i;
93  for(i=0;i<nrays;i++) {
94  double reading;
95  if(read_next_double(line,&cur,&reading)) {
96  sm_error("Could not read ray #%d / %d, \n", i, nrays);
97  on_error = 1;
98  break;
99  }
100 
101  ld->valid[i] = (reading > min_reading) && (reading < max_reading);
102  ld->readings[i] = ld->valid[i] ? reading : NAN;
103  ld->theta[i] = ld->min_theta + i *
104  (ld->max_theta-ld->min_theta) / (ld->nrays-1);
105 
106  /* bad hokuyo!! */
107  if(nrays == 769) {
108  if(i>725 || i<44) {
109  ld->valid[i] = 0;
110  ld->readings[i] = NAN;
111  }
112  }
113 
114  }
115 
116  if(on_error) goto error;
117 
118  if(read_next_double(line,&cur,ld->estimate+0)) goto error;
119  if(read_next_double(line,&cur,ld->estimate+1)) goto error;
120  if(read_next_double(line,&cur,ld->estimate+2)) goto error;
121  if(read_next_double(line,&cur,ld->odometry+0)) goto error;
122  if(read_next_double(line,&cur,ld->odometry+1)) goto error;
123  if(read_next_double(line,&cur,ld->odometry+2)) goto error;
124 
125  /* Following: ipc_timestamp hostname timestamp */
126  /* Two options:
127  double string double:
128  the first is timestamp in seconds, the second is discarded
129  int string int:
130  the first is sec, the second is usec
131  */
132  static int warn_format = 1;
133 
134  int inc; int sec=-1, usec=-1;
135  int res = sscanf(line + cur, "%d %s %d%n", &sec, ld->hostname, &usec, &inc);
136  if(3 == res) {
137  ld->tv.tv_sec = sec;
138  ld->tv.tv_usec = usec;
139  if(warn_format)
140  sm_info("Reading timestamp as 'sec hostname usec'.\n");
141  } else {
142  double v1=-1, v2=-1;
143  res = sscanf(line + cur, "%lf %s %lf%n", &v1, ld->hostname, &v2, &inc);
144  if(3 == res) {
145  ld->tv.tv_sec = (int) floor(v1);
146  ld->tv.tv_usec = floor( (v1 - floor(v1)) * 1e6 );
147 
148  if(warn_format)
149  sm_info("Reading timestamp as doubles (discarding second one).\n");
150 
151  } else {
152  ld->tv.tv_sec = 0;
153  ld->tv.tv_usec = 0;
154  if(warn_format)
155  sm_info("I could not read timestamp+hostname; ignoring (I will warn only once for this).\n");
156  }
157  }
158 
159  warn_format = 0;
160 
161  fprintf(stderr, "l");
162  return ld;
163 
164  error:
165  printf("Malformed line: '%s'\nat cur = %d\n\t-> '%s'\n", line,(int)cur,line+cur);
166  return 0;
167 }
168 
170 int ld_read_next_laser_carmen(FILE*file, LDP*ld) {
171  *ld = 0;
172  #define MAX_LINE_LENGTH 10000
173  char line[MAX_LINE_LENGTH];
174 
175  while(fgets(line, MAX_LINE_LENGTH-1, file)) {
176  if(0 != strncmp(line, carmen_prefix, strlen(carmen_prefix))) {
177  sm_debug("Skipping line: \n-> %s\n", line);
178  continue;
179  }
180 
181  *ld = ld_from_carmen_string(line);
182  if(!*ld) {
183  printf("Malformed line? \n-> '%s'", line);
184  return 0;
185  } else {
186  return 1;
187  }
188  }
189  return 1;
190 }
191 
193 void ld_write_as_carmen(LDP ld, FILE * stream) {
194  int i;
195  double timestamp;
196  if(!ld_valid_fields(ld)) {
197  sm_error("Writing bad data to the stream.\n");
198  }
199  fprintf(stream, "FLASER %d ", ld->nrays);
200  for(i=0; i<ld->nrays; i++){
201  fprintf(stream, "%g ", ld->readings[i]);
202  }
203  fprintf(stream, "%g %g %g ", ld->estimate[0], ld->estimate[1], ld->estimate[2]);
204  fprintf(stream, "%g %g %g ", ld->odometry[0], ld->odometry[1], ld->odometry[2]);
205 
206  timestamp = ld->tv.tv_sec + ((double)ld->tv.tv_sec)/1e6;
207 
208  fprintf(stream, "%g %s %g", timestamp, ld->hostname, timestamp);
209 
210  fputs("\n", stream);
211 }
212 
213 void ld_write_format(LDP ld, FILE*f, const char * out_format) {
214  if(!strncmp(out_format, "carmen", 6))
215  ld_write_as_carmen(ld, f);
216  else
217  ld_write_as_json(ld, f);
218  /* XXX: check validity of format string */
219 }
220 
221 
222 
223 
int *restrict valid
Definition: laser_data.h:23
#define deg2rad(x)
Definition: gpc_test.c:22
#define NAN
Definition: math_utils.h:11
double max_theta
Definition: laser_data.h:19
double min_theta
Definition: laser_data.h:18
char hostname[32]
Definition: laser_data.h:51
void ld_write_as_json(LDP ld, FILE *stream)
double odometry[3]
Definition: laser_data.h:39
void ld_write_format(LDP ld, FILE *f, const char *out_format)
int read_next_string(const char *line, size_t *cur, char *buf, size_t buf_len)
LDP ld_from_carmen_string(const char *line)
double *restrict theta
Definition: laser_data.h:21
int ld_valid_fields(LDP ld)
Definition: laser_data.c:179
int read_next_integer(const char *line, size_t *cur, int *d)
#define M_PI
Definition: math_utils.h:7
double *restrict readings
Definition: laser_data.h:24
int read_next_double(const char *line, size_t *cur, double *d)
void ld_write_as_carmen(LDP ld, FILE *stream)
double estimate[3]
Definition: laser_data.h:40
struct timeval tv
Definition: laser_data.h:50
void sm_debug(const char *msg,...)
Definition: logging.c:88
void sm_info(const char *msg,...)
Definition: logging.c:71
LDP ld_alloc_new(int nrays)
Definition: laser_data.c:12
const char * carmen_prefix
void sm_error(const char *msg,...)
Definition: logging.c:49
int ld_read_next_laser_carmen(FILE *file, LDP *ld)
#define MAX_LINE_LENGTH
char buf[100]
Definition: ld_recover.c:87
double rad2deg(double rad)
Definition: math_utils.c:79


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