odometry.c
Go to the documentation of this file.
1 // Copyright (c) 2010-2016 The YP-Spur Authors, except where otherwise indicated.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 
26 #include <fcntl.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <time.h>
31 
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif // HAVE_CONFIG_H
35 
36 /* ボディパラメータ */
37 #include <shvel-param.h>
38 
39 /* yp-spur用 */
40 #include <param.h>
41 #include <control.h>
42 #include <adinput.h>
43 #include <utility.h>
44 #include <yprintf.h>
45 #include <communication.h>
46 #include <serial.h>
47 #include <ssm_spur_handler.h>
48 
49 /* ライブラリ用 */
50 #include <ypspur.h>
51 #include <cartesian2d.h>
52 
53 double g_interval;
54 double g_offset;
56 double g_estimated_delay = 0;
57 
64 
67 
68 /* CS の初期化 */
70 {
71  /* */
72  g_BS = CS_add(0, 0, 0, 0); /* オドメトリ座標系 */
73  g_GL = CS_add(g_BS, 0, 0, 0); /* グローバル座標系 */
74  g_LC = CS_add(g_GL, 0, 0, 0); /* ローカル座標系 */
75  g_FS = CS_add(g_BS, 0, 0, 0); /* 自己位置 */
76  g_BL = CS_add(g_BS, 0, 0, 0); /* オドメトリローカル座標系 */
77  g_SP = CS_add(g_BS, 0, 0, 0); /* Spur座標系(走行制御用) */
78 }
79 
80 void init_odometry(void)
81 {
82  int i;
83  g_odometry.x = 0;
84  g_odometry.y = 0;
85  g_odometry.theta = 0;
86  for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
87  {
88  g_odometry.enc[i] = 0;
89  g_odometry.enc_init[i] = 0;
90  g_odometry.wang[i] = 0;
91  g_odometry.wtorque[i] = 0;
92  g_odometry.wvel[i] = 0;
93  g_error_state.state[i] = 0;
94  g_error_state.time[i] = 0;
95  }
96  g_odometry.v = 0;
97  g_odometry.w = 0;
98  g_odometry.time = 0;
99  g_odometry.packet_lost = 0;
100  g_offset_point = 0;
101 }
102 
104 {
105  switch (cs)
106  {
107  case CS_FS:
108  return g_FS;
109  break;
110  case CS_LC:
111  return g_LC;
112  break;
113  case CS_GL:
114  return g_GL;
115  break;
116  case CS_SP:
117  return g_SP;
118  break;
119  case CS_BS:
120  return g_BS;
121  break;
122  case CS_BL:
123  return g_BL;
124  break;
125  default:
126  return NULL;
127  break;
128  }
129  return NULL;
130 }
131 
132 void cstrans_xy(YPSpur_cs src, YPSpur_cs dest, double *x, double *y, double *theta)
133 {
134  if (src == dest)
135  return;
136  CS_recursive_trans(get_cs_pointer(dest), get_cs_pointer(src), x, y, theta);
137 }
138 
139 void set_cs(YPSpur_cs cs, double x, double y, double theta)
140 {
141  CS_set(get_cs_pointer(cs), x, y, theta);
142 }
143 
144 /* オドメトリ計算 */
145 void odometry(OdometryPtr xp, short *cnt, short *pwm, double dt, double time)
146 {
147  double v, w;
149  double mtorque[YP_PARAM_MAX_MOTOR_NUM], wtorque[YP_PARAM_MAX_MOTOR_NUM];
151  double torque_trans, torque_angular;
152  Parameters *param;
153  param = get_param_ptr();
154 
155  int i;
156  for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
157  {
158  if (!param->motor_enable[i])
159  continue;
160 
161  short cnt_diff;
162  if (param->device_version > 8)
163  {
164  cnt_diff = (short)cnt[i] - (short)xp->enc[i];
165  xp->enc[i] = cnt[i];
166  if (!xp->enc_init[i])
167  {
168  cnt_diff = 0;
169  if (cnt[i] != 0)
170  {
171  xp->enc_init[i] = 1;
172  }
173  }
174  }
175  else
176  {
177  cnt_diff = cnt[i];
178  xp->enc[i] += cnt_diff;
179  }
180 
181  /* 角速度計算 */
182  mvel[i] = 2.0 * M_PI *
183  ((double)cnt_diff) * pow(2, p(YP_PARAM_ENCODER_DIV, i)) /
184  (p(YP_PARAM_COUNT_REV, i) * dt);
185  wvel[i] = mvel[i] / p(YP_PARAM_GEAR, i);
186 
187  /* トルク推定 */
188  volt[i] = (double)pwm[i] * p(YP_PARAM_VOLT, i) / (p(YP_PARAM_PWM_MAX, i) * (dt / p(YP_PARAM_CYCLE, i)));
189  vc[i] = (p(YP_PARAM_MOTOR_VC, i) / 60) * 2 * M_PI; // [rpm/V] => [(rad/s)/V]
190  // TC [Nm/A]
191  mtorque[i] = (p(YP_PARAM_MOTOR_TC, i) * (volt[i] - mvel[i] / vc[i])) /
193  /* 摩擦補償の補償 */
194  if (wvel[i] > 0)
195  {
196  mtorque[i] -= p(YP_PARAM_TORQUE_NEWTON, i) + p(YP_PARAM_TORQUE_VISCOS, i) * fabs(mvel[i]);
197  }
198  else if (wvel[i] < 0)
199  {
200  mtorque[i] += p(YP_PARAM_TORQUE_NEWTON_NEG, i) + p(YP_PARAM_TORQUE_VISCOS_NEG, i) * fabs(mvel[i]);
201  }
202  wtorque[i] = mtorque[i] * p(YP_PARAM_GEAR, i);
203  }
204 
205  /* キネマティクス計算 */
206  v = p(YP_PARAM_RADIUS, MOTOR_RIGHT) * wvel[MOTOR_RIGHT] / 2.0 + p(YP_PARAM_RADIUS, MOTOR_LEFT) * wvel[MOTOR_LEFT] / 2.0;
208 
209  torque_trans = wtorque[MOTOR_RIGHT] / p(YP_PARAM_RADIUS, MOTOR_RIGHT) + wtorque[MOTOR_LEFT] / p(YP_PARAM_RADIUS, MOTOR_LEFT);
210  torque_angular = (+wtorque[MOTOR_RIGHT] / p(YP_PARAM_RADIUS, MOTOR_RIGHT) - wtorque[MOTOR_LEFT] / p(YP_PARAM_RADIUS, MOTOR_LEFT)) * p(YP_PARAM_TREAD, 0) / 2;
211 
212  /* オドメトリ計算 */
213  xp->x = xp->x + v * cos(xp->theta) * dt;
214  xp->y = xp->y + v * sin(xp->theta) * dt;
215  xp->theta = xp->theta + w * dt;
216  xp->time = time;
218  {
219  static int cnt = 0;
220  if (++cnt % 100 == 0)
221  printf("now - stamp: %0.3f ms\n", (get_time() - time) * 1000.0);
222  }
223  xp->v = v;
224  xp->w = w;
225  for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
226  {
227  if (!param->motor_enable[i])
228  continue;
229  xp->wvel[i] = wvel[i];
230  xp->wang[i] = xp->wang[i] + xp->wvel[i] * dt;
231  xp->wtorque[i] = wtorque[i];
232  }
233  xp->torque_trans = torque_trans;
234  xp->torque_angular = torque_angular;
235 
236  /*-PI< <PIに調整*/
237  // if(xp->theta <-M_PI)xp->theta += 2*M_PI;
238  // if(xp->theta > M_PI)xp->theta -= 2*M_PI;
239 
240  /* FS座標系セット */
241  CS_set(g_FS, xp->x, xp->y, xp->theta);
242 
243  // 数式指定のパラメータを評価
244  param_calc();
245 }
246 
247 /* 割り込み型データの処理 */
249  OdometryPtr xp, ErrorStatePtr err, int param_id, int id, int value, double receive_time)
250 {
251  Parameters *param;
252  param = get_param_ptr();
253 
254  switch (param_id)
255  {
256  case INT_enc_index_rise:
257  case INT_enc_index_fall:
258  {
259  if (id >= YP_PARAM_MAX_MOTOR_NUM || !param->motor_enable[id])
260  return;
261 
262  // enc == value のときに INDEX_RISE/FALL_ANGLE [rad] だった
263  const unsigned short enc_div =
264  ((unsigned int)xp->enc[id] << ((int)p(YP_PARAM_ENCODER_DIV, id))) & 0xFFFF;
265  const short enc_diff = (short)enc_div - (short)value;
266  const double ang_diff =
267  enc_diff * 2.0 * M_PI / (p(YP_PARAM_COUNT_REV, id) * p(YP_PARAM_GEAR, id));
268 
269  const double index_ratio = p(YP_PARAM_INDEX_GEAR, id) / p(YP_PARAM_GEAR, id);
270  double ref_ang;
271  if (param_id == INT_enc_index_rise)
272  {
274  break;
275  ref_ang = p(YP_PARAM_INDEX_RISE_ANGLE, id);
276  }
277  else
278  {
280  break;
281  ref_ang = p(YP_PARAM_INDEX_FALL_ANGLE, id);
282  }
283 
284  ref_ang *= index_ratio;
285 
286  xp->wang[id] = round((xp->wang[id] - ref_ang - ang_diff) / (2.0 * M_PI * index_ratio)) *
287  2.0 * M_PI * index_ratio +
288  ref_ang + ang_diff;
289  break;
290  }
291  case INT_error_state:
292  {
293  if (id >= YP_PARAM_MAX_MOTOR_NUM || !param->motor_enable[id])
294  return;
295 
296  if (err->state[id] != value)
297  {
298  if (value == ERROR_NONE)
299  {
300  yprintf(OUTPUT_LV_INFO, "Info: The driver of motor_id %d got back to normal\n", id);
301  }
302  else
303  {
304  yprintf(OUTPUT_LV_ERROR, "Error: The driver of motor_id %d returned ", id);
305 
306  if (value & ERROR_LOW_VOLTAGE)
307  yprintf(OUTPUT_LV_ERROR, "ERROR_LOW_VOLTAGE ");
308  if (value & ERROR_HALL_SEQ)
309  yprintf(OUTPUT_LV_ERROR, "ERROR_HALL_SEQ ");
310  if (value & ERROR_HALL_ENC)
311  yprintf(OUTPUT_LV_ERROR, "ERROR_HALL_ENC ");
312  if (value & ERROR_WATCHDOG)
313  yprintf(OUTPUT_LV_ERROR, "ERROR_WATCHDOG ");
314  if (value & ERROR_EEPROM)
315  yprintf(OUTPUT_LV_ERROR, "ERROR_EEPROM ");
316  if (value & ERROR_INTERNAL)
317  yprintf(OUTPUT_LV_ERROR, "ERROR_INTERNAL ");
318 
319  yprintf(OUTPUT_LV_ERROR, "\n");
320  }
321  }
322  err->state[id] = value;
323  err->time[id] = receive_time;
324  break;
325  }
326  case INT_ping_response:
327  if (id == MOTOR_ID_BROADCAST)
328  {
330  yprintf(OUTPUT_LV_INFO, "Ping response received: broadcast, 0x%08x\n", value);
331  }
332  else
333  {
334  xp->ping_response[id] = value;
335  yprintf(OUTPUT_LV_INFO, "Ping response received: %d, 0x%08x\n", id, value);
336  }
337  break;
338  default:
339  yprintf(OUTPUT_LV_ERROR, "Error: Unknown interrupt data (%d, %d, %d)\n", param_id, id, value);
340  break;
341  }
342 }
343 
344 /* Odometry型データの座標系を変換 */
346 {
347  double x, y, theta;
348  x = g_odometry.x;
349  y = g_odometry.y;
350  theta = g_odometry.theta;
351 
352  CS_recursive_trans(get_cs_pointer(cs), g_BS, &x, &y, &theta);
353 
354  dst_odm->x = x;
355  dst_odm->y = y;
356  dst_odm->theta = theta;
357  dst_odm->time = g_odometry.time;
358 }
359 
360 /* オドメトリへのポインタを取得 */
362 {
363  return &g_odometry;
364 }
365 
367 {
368  return &g_error_state;
369 }
370 
375 double time_estimate(int readnum)
376 {
377  return g_offset + g_interval * (double)(readnum - g_offset_point) + g_estimated_delay;
378 }
379 
386 double time_synchronize(double receive_time, int readnum, int wp)
387 {
388  static double prev_time = 0.0;
389  static int prev_readnum = 0;
390  double measured_time;
391 
392  // 受信開始時刻を計算
393  if (SER_BAUDRATE != 0)
394  {
395  measured_time = receive_time - (wp / (SER_BAUDRATE / 8.0));
396  }
397  else
398  {
399  measured_time = receive_time;
400  }
401  // Add half USB FS frame delay
402  // (Currently all YP-Spur compatible devices uses USB as a communication interface.)
403  measured_time -= 0.0005;
404 
405  if (g_offset_point <= 0 || fabs(g_offset - measured_time) > 0.5)
406  {
407  // Reset if measured_time has too large error (500ms).
408  g_offset = measured_time;
410  g_offset_point = readnum;
411  prev_time = measured_time;
412  }
413 
414  // predict
415  g_offset += g_interval * (readnum - g_offset_point);
416  g_offset_point = readnum;
417 
418  const double dt = measured_time - prev_time;
419  double error = measured_time - g_offset;
420 
421  const int lost = lround(error / g_interval);
422  if (lost != 0)
423  {
424  g_odometry.packet_lost += lost;
426  yprintf(OUTPUT_LV_WARNING, "%d packets might be lost!\n", lost);
427 
428  error -= lost * g_interval;
429  g_offset_point -= lost;
430  }
431  else if (g_odometry.packet_lost_last != g_odometry.packet_lost)
432  {
433  // Discard lost=+1/-1 as a jitter.
434  if (abs(g_odometry.packet_lost_last - g_odometry.packet_lost) > 1)
435  yprintf(OUTPUT_LV_ERROR, "Error: total packet lost: %d\n", g_odometry.packet_lost);
436  g_odometry.packet_lost_last = g_odometry.packet_lost;
437  }
438 
439  static double error_integ = 0;
440  error_integ += error * dt;
441 
442  if (error < g_estimated_delay && lost == 0)
443  {
445  printf("[update min_delay] delay: %0.3f\n",
446  error * 1000.0);
447  g_estimated_delay = g_estimated_delay * 0.5 + error * 0.5;
448  }
449  g_estimated_delay *= (1.0 - dt / 120.0);
450 
451  g_offset += error * 0.2 + error_integ * 0.1;
452 
453  // aprox. 0.5 sec exp filter
454  g_interval =
455  0.99 * g_interval +
456  0.01 * ((measured_time - prev_time) / (double)(readnum - prev_readnum));
457 
458  static int cnt_show_timestamp = 0;
459  if (option(OPTION_SHOW_TIMESTAMP) && ++cnt_show_timestamp % 100 == 0)
460  printf("epoch: %0.8f, interval: %0.3f, delay: %0.3f, min_delay: %0.3f\n",
461  g_offset, g_interval * 1000.0, error * 1000.0, g_estimated_delay * 1000.0);
462 
463  prev_time = measured_time;
464  prev_readnum = readnum;
465 
466  return g_offset;
467 }
468 
469 /* シリアル受信処理 */
470 int odometry_receive(char *buf, int len, double receive_time, void *data)
471 {
472  static int com_wp = 0;
473  static int receive_count = 0;
474  static char com_buf[128];
475  static enum
476  {
477  ISOCHRONOUS = 0,
478  INTERRUPT
479  } mode = 0;
480 
481  int i;
482  int odometry_updated;
483  int readdata_num;
484  int decoded_len = 0;
485  int decoded_len_req; // Expected length of the data
486  int readdata_len = 0;
487 
488  // Odometry *odm;
489  Odometry odm_log[100];
490  Short_2Char cnt1_log[100];
491  Short_2Char cnt2_log[100];
492  Short_2Char pwm1_log[100];
493  Short_2Char pwm2_log[100];
494  int ad_log[100][8];
495  Parameters *param;
496 
497  param = get_param_ptr();
498 
499  decoded_len_req =
500  (+get_ad_num() /* ad */
501  + get_dio_num() /* dio */
502  + param->num_motor_enable * 2 /* cnt + pwm */
503  ) *
504  2 /* data cnt -> byte */;
505  readdata_num = 0;
506  odometry_updated = 0;
507  // 読み込まれたデータを解析
508  for (i = 0; i < len; i++)
509  {
510  if (buf[i] == COMMUNICATION_START_BYTE)
511  {
512  com_wp = 0;
513  mode = ISOCHRONOUS;
514  }
515  else if (buf[i] == COMMUNICATION_INT_BYTE)
516  {
517  com_wp = 0;
518  mode = INTERRUPT;
519  }
520  else if (buf[i] == COMMUNICATION_END_BYTE)
521  {
522  unsigned char data[48];
523 
524  /* デコード処理 */
525  decoded_len = decode((unsigned char *)com_buf, com_wp, (unsigned char *)data, 48);
526 
527  switch (mode)
528  {
529  case ISOCHRONOUS:
530  {
531  if (decoded_len != decoded_len_req)
532  {
533  com_buf[com_wp] = '\0';
534  yprintf(OUTPUT_LV_WARNING, "Warn: Broken packet '%s' (%d bytes) received. (%d bytes expected)\n", com_buf, decoded_len, decoded_len_req);
535  com_wp = 0;
536  continue;
537  }
538 
540  int i, p = 0;
541  for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
542  {
543  if (!param->motor_enable[i])
544  continue;
545  Short_2Char val;
546  val.byte[1] = data[p++];
547  val.byte[0] = data[p++];
548  cnt[i] = val.integer;
549  }
550  for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
551  {
552  if (!param->motor_enable[i])
553  continue;
554  Short_2Char val;
555  val.byte[1] = data[p++];
556  val.byte[0] = data[p++];
557  pwm[i] = val.integer;
558  }
559 
560  process_addata(&data[p], decoded_len - p);
561 
562  cnt1_log[readdata_num].integer = cnt[0];
563  cnt2_log[readdata_num].integer = cnt[1];
564  pwm1_log[readdata_num].integer = pwm[0];
565  pwm2_log[readdata_num].integer = pwm[1];
566  memcpy(ad_log[readdata_num], get_addataptr(), sizeof(int) * 8);
567  readdata_num++;
568 
570  {
571  odometry(&g_odometry, cnt, pwm, g_interval, time_estimate(receive_count + readdata_num));
572  odm_log[odometry_updated] = g_odometry;
573  odometry_updated++;
574  }
575 
577  printf("%f %f %f\n", g_odometry.x, g_odometry.y, g_odometry.theta);
578  }
579  break;
580  case INTERRUPT:
581  {
582  const char param = data[0];
583  const char id = data[1];
584 
585  switch (param)
586  {
587  case INT_debug_dump:
588  {
589  const unsigned char cnt = data[2];
590  yprintf(OUTPUT_LV_INFO, "Dump: %02x %x ", id, cnt);
591  int i;
592  for (i = 3; i < decoded_len; i++)
593  {
594  yprintf(OUTPUT_LV_INFO, " %02x", data[i]);
595  }
596  yprintf(OUTPUT_LV_INFO, "\n");
597  }
598  break;
599  default:
600  {
601  if (decoded_len != 6)
602  {
603  com_buf[com_wp] = '\0';
604  yprintf(OUTPUT_LV_WARNING, "Warn: Broken packet '%s' (%d bytes) received. (%d bytes expected)\n", com_buf, decoded_len, 6);
605  com_wp = 0;
606  continue;
607  }
608 
609  Int_4Char value;
610  value.byte[3] = data[2];
611  value.byte[2] = data[3];
612  value.byte[1] = data[4];
613  value.byte[0] = data[5];
614 
615  process_int4(&g_odometry, &g_error_state, param, id, value.integer, receive_time);
616  }
617  break;
618  }
619  }
620  break;
621  }
622  readdata_len = com_wp;
623  com_wp = 0;
624  }
625  else
626  {
627  com_buf[com_wp] = buf[i];
628  com_wp++;
629  if (com_wp >= 128)
630  {
631  com_wp = 128 - 1;
632  yprintf(OUTPUT_LV_WARNING, "Warn: Read buffer overrun.\n");
633  }
634  }
635  }
636 
637  if (readdata_num > 0)
638  {
639  receive_count += readdata_num;
640  if (com_wp == 0)
641  time_synchronize(receive_time, receive_count, com_wp);
642  }
643 
644  write_ypspurSSM(odometry_updated, receive_count, odm_log, readdata_num, cnt1_log, cnt2_log, pwm1_log, pwm2_log,
645  ad_log);
646  return 1;
647 }
648 
650 {
651  int ret;
652  Parameters *param;
653  param = get_param_ptr();
654 
656  while (1)
657  {
658  ret = serial_recieve(odometry_receive, NULL);
659  if (param->parameter_applying)
660  {
661  yprintf(OUTPUT_LV_INFO, "Restarting odometry receive loop.\n");
662  continue;
663  }
664  break;
665  }
666 
667  return ret;
668 }
void odometry(OdometryPtr xp, short *cnt, short *pwm, double dt, double time)
Definition: odometry.c:145
Definition: ypparam.h:491
int odometry_receive(char *buf, int len, double receive_time, void *data)
Definition: odometry.c:470
int packet_lost
Definition: odometry.h:47
double SER_BAUDRATE
Definition: serial.c:48
CSptr CS_add(CSptr parent_cs, double x, double y, double theta)
Definition: libcarte2d.c:31
double torque_angular
Definition: odometry.h:45
int process_addata(unsigned char *buf, int len)
Definition: adinput.c:52
double y
Definition: odometry.h:34
void cstrans_xy(YPSpur_cs src, YPSpur_cs dest, double *x, double *y, double *theta)
Definition: odometry.c:132
int enc_init[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:42
void CS_recursive_trans(CSptr target_cs, CSptr now_cs, double *x, double *y, double *theta)
Definition: libcarte2d.c:137
double get_time(void)
Definition: utility.c:45
Definition: ypparam.h:495
double time
Definition: odometry.h:38
short enc[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:41
double p(YPSpur_param id, enum motor_id motor)
Definition: param.c:79
void set_cs(YPSpur_cs cs, double x, double y, double theta)
Definition: odometry.c:139
Definition: ypparam.h:492
double wang[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:40
void init_odometry(void)
Definition: odometry.c:80
short integer
Definition: shvel-param.h:34
#define MOTOR_ID_BROADCAST
Definition: shvel-param.h:128
int g_offset_point
Definition: odometry.c:55
void process_int4(OdometryPtr xp, ErrorStatePtr err, int param_id, int id, int value, double receive_time)
Definition: odometry.c:248
double wtorque[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:43
double g_estimated_delay
Definition: odometry.c:56
int integer
Definition: shvel-param.h:28
CSptr g_SP
Definition: odometry.c:59
int CS_set(CSptr target_cs, double x, double y, double theta)
Definition: libcarte2d.c:100
void param_calc()
Definition: param.c:434
char byte[2]
Definition: shvel-param.h:35
int packet_lost_last
Definition: odometry.h:48
double w
Definition: odometry.h:37
#define COMMUNICATION_END_BYTE
Definition: communication.h:26
int odometry_receive_loop(void)
Definition: odometry.c:649
double v
Definition: odometry.h:36
Definition: ypparam.h:494
ErrorStatePtr get_error_state_ptr()
Definition: odometry.c:366
int get_ad_num(void)
Definition: adinput.c:85
int decode(const unsigned char *src, int len, unsigned char *dst, int buf_max)
デコード
Definition: communication.c:86
void cstrans_odometry(YPSpur_cs cs, OdometryPtr dst_odm)
Definition: odometry.c:345
CSptr g_BS
Definition: odometry.c:61
int ping_response[YP_PARAM_MAX_MOTOR_NUM+1]
Definition: odometry.h:46
int num_motor_enable
Definition: param.h:86
CSptr g_BL
Definition: odometry.c:63
#define YP_PARAM_MAX_MOTOR_NUM
Definition: ypparam.h:456
int serial_recieve(int(*serial_event)(char *, int, double, void *), void *data)
Definition: serial.c:434
double theta
Definition: odometry.h:35
CSptr g_FS
Definition: odometry.c:62
char byte[4]
Definition: shvel-param.h:29
double wvel[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:39
void yprintf(ParamOutputLv level, const char *format,...)
Definition: yprintf.c:32
int motor_enable[YP_PARAM_MAX_MOTOR_NUM]
Definition: param.h:85
double g_offset
Definition: odometry.c:54
CSptr g_LC
Definition: odometry.c:60
double torque_trans
Definition: odometry.h:44
Definition: ypparam.h:493
int get_dio_num(void)
Definition: adinput.c:90
#define SER_INTERVAL
(Byte/sec) シリアルの通信速度
Definition: serial.h:31
int state(YPSpur_state id)
Definition: param.c:64
int option(ParamOptions option)
Definition: param.c:99
ErrorState g_error_state
Definition: odometry.c:66
int device_version
Definition: param.h:87
int isset_p(YPSpur_param id, enum motor_id motor)
Definition: param.c:84
void write_ypspurSSM(int odometry_updated, int receive_count, Odometry *odm_log, int readdata_num, Short_2Char *cnt1_log, Short_2Char *cnt2_log, Short_2Char *pwm1_log, Short_2Char *pwm2_log, int ad_log[][8])
double time[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:55
CSptr get_cs_pointer(YPSpur_cs cs)
Definition: odometry.c:103
const int * get_addataptr()
Definition: adinput.c:71
#define COMMUNICATION_INT_BYTE
Definition: communication.h:25
double time_synchronize(double receive_time, int readnum, int wp)
ビットレートとか読み込める文字数を観測時刻の推定
Definition: odometry.c:386
ParametersPtr get_param_ptr()
Definition: param.c:111
OdometryPtr get_odometry_ptr()
Definition: odometry.c:361
CSptr g_GL
Definition: odometry.c:58
YPSpur_cs
Definition: ypparam.h:488
Definition: ypparam.h:490
double g_interval
Definition: odometry.c:53
double x
Definition: odometry.h:33
int parameter_applying
Definition: param.h:89
YPSpur_shvel_error_state state[YP_PARAM_MAX_MOTOR_NUM]
Definition: odometry.h:54
double time_estimate(int readnum)
時刻の推定 (n回目の計測結果の時刻を計算する)
Definition: odometry.c:375
void init_coordinate_systems(void)
Definition: odometry.c:69
Odometry g_odometry
Definition: odometry.c:65
#define COMMUNICATION_START_BYTE
Definition: communication.h:24


yp-spur
Author(s):
autogenerated on Fri May 7 2021 02:12:17