5 * @brief Module providing communication through ORTE
9 * robot_orte.c 08/04/21
11 * Robot's orte stuffs.
13 * Copyright: (c) 2008-2010 CTU Dragons
14 * CTU FEE - Department of Control Engineering
15 * License: GNU GPL v.2
19 #include <roboorte_robottype.h>
22 #include <movehelper.h>
25 #include "map_handling.h"
28 #include <can_msg_def.h>
31 #define DBG(format, ...) printf(format, ##__VA_ARGS__)
33 #define DBG(format, ...)
37 extern sem_t measurement_received;
39 /* ----------------------------------------------------------------------
40 * PUBLISHER CALLBACKS - GENERIC
41 * ---------------------------------------------------------------------- */
43 void send_ref_pos_cb(const ORTESendInfo *info, void *vinstance,
44 void *sendCallBackParam)
46 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
49 *instance = robot.ref_pos;
50 ROBOT_UNLOCK(ref_pos);
53 void send_est_pos_uzv_cb(const ORTESendInfo *info, void *vinstance,
54 void *sendCallBackParam)
56 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
58 ROBOT_LOCK(est_pos_uzv);
59 *instance = robot.est_pos_uzv;
60 ROBOT_UNLOCK(est_pos_uzv);
63 void send_est_pos_odo_cb(const ORTESendInfo *info, void *vinstance,
64 void *sendCallBackParam)
66 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
68 ROBOT_LOCK(est_pos_odo);
69 *instance = robot.est_pos_odo;
70 ROBOT_UNLOCK(est_pos_odo);
73 void send_dummy_cb(const ORTESendInfo *info, void *vinstance,
74 void *sendCallBackParam)
78 /* ----------------------------------------------------------------------
79 * SUBSCRIBER CALLBACKS - GENERIC
80 * ---------------------------------------------------------------------- */
82 void rcv_odo_data_cb(const ORTERecvInfo *info, void *vinstance,
83 void *recvCallBackParam)
86 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
87 double dleft, dright, dtang, dphi;
88 static bool first_run = true;
89 /* spocitat prevodovy pomer */
90 const double n = (double)(28.0 / 1.0);
92 /* vzdalenost na pulz IRC */
93 const double c = (M_PI*2*ROBOT_WHEEL_RADIUS_M) / (n * 4*500.0);
95 /* TODO: Michal - dodelat */
96 switch (info->status) {
99 ROBOT_LOCK(motion_irc);
100 robot.motion_irc = *instance;
101 ROBOT_UNLOCK(motion_irc);
106 dleft = ((robot.motion_irc.left - instance->left) >> 8) * c;
107 dright = ((instance->right - robot.motion_irc.right) >> 8) * c;
109 dtang = (dleft + dright) / 2.0;
110 dphi = (dright - dleft) / (2.0*ROBOT_ROTATION_RADIUS_M);
112 ROBOT_LOCK(est_pos_odo);
113 double a = robot.est_pos_odo.phi;
114 robot.est_pos_odo.x += dtang*cos(a);
115 robot.est_pos_odo.y += dtang*sin(a);
116 robot.est_pos_odo.phi += dphi;
117 ROBOT_UNLOCK(est_pos_odo);
119 /* locking should not be needed, but... */
120 ROBOT_LOCK(motion_irc);
121 robot.motion_irc = *instance;
122 robot.motion_irc_received = 1;
123 ROBOT_UNLOCK(motion_irc);
125 robot.odometry_works = true;
127 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
130 robot.odometry_works = false;
131 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
132 DBG("ORTE deadline occurred - motion_irc receive\n");
140 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
141 void *recvCallBackParam)
143 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
144 double dleft, dright, dtang, dphi;
145 static bool first_run = true;
146 /* spocitat prevodovy pomer */
147 const double n = (double)(28.0 / 1.0);
149 /* vzdalenost na pulz IRC */
150 const double c = (M_PI*2*ROBOT_WHEEL_RADIUS_M) / (n * 4*500.0);
152 switch (info->status) {
155 ROBOT_LOCK(motion_irc);
156 robot.motion_irc = *instance;
157 ROBOT_UNLOCK(motion_irc);
162 dleft = ((robot.motion_irc.left - instance->left) >> 8) * c;
163 dright = ((instance->right - robot.motion_irc.right) >> 8) * c;
165 dtang = (dleft + dright) / 2.0;
166 dphi = (dright - dleft) / (2.0*ROBOT_ROTATION_RADIUS_M);
168 ROBOT_LOCK(est_pos_odo);
169 double a = robot.est_pos_odo.phi;
170 robot.est_pos_odo.x += dtang*cos(a);
171 robot.est_pos_odo.y += dtang*sin(a);
172 robot.est_pos_odo.phi += dphi;
173 ROBOT_UNLOCK(est_pos_odo);
175 /* locking should not be needed, but... */
176 ROBOT_LOCK(motion_irc);
177 robot.motion_irc = *instance;
178 robot.motion_irc_received = 1;
179 ROBOT_UNLOCK(motion_irc);
181 robot.odometry_works = true;
183 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
186 robot.odometry_works = false;
187 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
188 DBG("ORTE deadline occurred - motion_irc receive\n");
193 void rcv_corr_distances_cb(const ORTERecvInfo *info, void *vinstance,
194 void *recvCallBackParam)
196 struct corr_distances_type *instance =
197 (struct corr_distances_type *)vinstance;
199 switch (info->status) {
201 /* locking should not be needed, but... */
202 ROBOT_LOCK(corr_distances);
203 robot.corr_distances = *instance;
204 ROBOT_UNLOCK(corr_distances);
206 /* wake up motion-control/thread_trajectory_follower */
207 sem_post(&measurement_received);
209 /*FIXME: is following OK? (pecam1) */
210 robot.hw_status[STATUS_UZV] = HW_STATUS_OK;
213 robot.hw_status[STATUS_UZV] = HW_STATUS_FAILED;
219 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
220 void *recvCallBackParam)
222 switch (info->status) {
226 DBG("ORTE deadline occurred - motion_speed receive\n");
231 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
232 void *recvCallBackParam)
234 switch (info->status) {
238 DBG("ORTE deadline occurred - motion_status receive\n");
243 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
244 void *recvCallBackParam)
246 switch (info->status) {
248 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
251 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
252 DBG("ORTE deadline occurred - pwr_voltage receive\n");
257 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
258 void *recvCallBackParam)
260 switch (info->status) {
264 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
269 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
270 void *recvCallBackParam)
272 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
273 static struct robot_cmd_type last_instance;
275 switch (info->status) {
277 /* Stupid way of controlling the robot by
278 * pluggin in and out start connector. */
279 switch (robot.state) {
281 if (instance->start) {
282 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
284 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
286 if (!instance->start) {
287 robot.state = START_PLUGGED_IN;
288 printf("START_PLUGGED_IN\n");
292 case START_PLUGGED_IN:
293 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
294 /* Competition starts when plugged out */
295 if (instance->start) {
296 FSM_SIGNAL(MAIN, EV_START, NULL);
297 robot.state = COMPETITION_STARTED;
302 case COMPETITION_STARTED: {
303 /* Subsequent plug-in stops the robot */
305 if (!instance->start) {
306 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
313 last_instance = *instance;
316 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
317 DBG("ORTE deadline occurred - robot_cmd receive\n");
322 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
323 void *recvCallBackParam)
325 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
327 switch (info->status) {
330 robot.hokuyo = *instance;
331 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
332 ROBOT_UNLOCK(hokuyo);
333 update_map_hokuyo(instance);
337 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
338 //system("killall -9 hokuyo");
339 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
344 // FIXME: this is not up to date (Filip, 2010)
345 void rcv_camera_result_cb(const ORTERecvInfo *info, void *vinstance,
346 void *recvCallBackParam)
348 struct camera_result_type *instance = (struct camera_result_type *)vinstance;
350 switch (info->status) {
352 ROBOT_LOCK(camera_result);
353 robot.game_conf = instance->lot;
354 ROBOT_UNLOCK(camera_result);
355 robot.hw_status[STATUS_CAM] = HW_STATUS_OK;
359 if (robot.orte.camera_control.on) {
360 robot.hw_status[STATUS_CAM] = HW_STATUS_FAILED;
361 //system("killall -9 rozpuk");
364 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
368 /* ----------------------------------------------------------------------
369 * SUBSCRIBER CALLBACKS - EB2008
370 * ---------------------------------------------------------------------- */
372 // FIXME: this is not up to date (Filip, 2010)
373 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
374 void *recvCallBackParam)
376 switch (info->status) {
378 // new data arrived and requested position equals actual position
381 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
382 DBG("ORTE deadline occurred - actuator_status receive\n");
389 static int cmp_double(const void *v1, const void *v2)
391 const double *d1 = v1, *const d2 = v2;
401 int robot_init_orte()
405 robot.orte.strength = 20;
407 rv = robottype_roboorte_init(&robot.orte);
411 /* creating publishers */
412 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
413 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
414 robottype_publisher_est_pos_uzv_create(&robot.orte, send_est_pos_uzv_cb, &robot.orte);
415 robottype_publisher_est_pos_odo_create(&robot.orte, send_est_pos_odo_cb, &robot.orte);
416 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
418 // I didn't know what was the difference between the callback function pointer
419 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
421 // - NULL: message is published only when OrtePublicationSend called
422 // - pointer to empty function: message is published periodically
423 robottype_publisher_fsm_main_create(&robot.orte, send_dummy_cb, &robot.orte);
424 robottype_publisher_fsm_act_create(&robot.orte, send_dummy_cb, &robot.orte);
425 robottype_publisher_fsm_motion_create(&robot.orte, send_dummy_cb, &robot.orte);
426 robottype_publisher_camera_control_create(&robot.orte, send_dummy_cb, &robot.orte);
428 /* create generic subscribers */
429 robottype_subscriber_odo_data_create(&robot.orte, rcv_odo_data_cb, &robot.orte);
430 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
431 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
432 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
433 robottype_subscriber_corr_distances_create(&robot.orte, rcv_corr_distances_cb, &robot.orte);
434 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
435 //robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
436 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
437 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
439 /* create subscribers */ // FIXME: these two may be obsolete this year (Filip, 2010)
440 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
441 robottype_subscriber_camera_result_create(&robot.orte, rcv_camera_result_cb, &robot.orte);