2 * robot_orte.c 08/04/21
6 * Copyright: (c) 2008 CTU Dragons
7 * CTU FEE - Department of Control Engineering
12 #include <roboorte_robottype.h>
15 #include <movehelper.h>
18 #include <laser-nav.h>
19 #include "map_handling.h"
22 #include <can_msg_def.h>
25 #define DBG(format, ...) printf(format, ##__VA_ARGS__)
27 #define DBG(format, ...)
31 extern sem_t measurement_received;
33 /* ----------------------------------------------------------------------
34 * PUBLISHER CALLBACKS - GENERIC
35 * ---------------------------------------------------------------------- */
37 void send_ref_pos_cb(const ORTESendInfo *info, void *vinstance,
38 void *sendCallBackParam)
40 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
43 *instance = robot.ref_pos;
44 ROBOT_UNLOCK(ref_pos);
47 void send_est_pos_uzv_cb(const ORTESendInfo *info, void *vinstance,
48 void *sendCallBackParam)
50 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
52 ROBOT_LOCK(est_pos_uzv);
53 *instance = robot.est_pos_uzv;
54 ROBOT_UNLOCK(est_pos_uzv);
57 void send_est_pos_odo_cb(const ORTESendInfo *info, void *vinstance,
58 void *sendCallBackParam)
60 struct robot_pos_type *instance = (struct robot_pos_type *)vinstance;
62 ROBOT_LOCK(est_pos_odo);
63 *instance = robot.est_pos_odo;
64 ROBOT_UNLOCK(est_pos_odo);
67 void send_dummy_cb(const ORTESendInfo *info, void *vinstance,
68 void *sendCallBackParam)
72 /* ----------------------------------------------------------------------
73 * SUBSCRIBER CALLBACKS - GENERIC
74 * ---------------------------------------------------------------------- */
76 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
77 void *recvCallBackParam)
79 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
80 double dleft, dright, dtang, dphi;
81 static bool first_run = true;
82 /* spocitat prevodovy pomer */
83 const double n = (double)(28.0 / 1.0);
85 /* vzdalenost na pulz IRC */
86 const double c = (M_PI*2*ROBOT_WHEEL_RADIUS_M) / (n * 4*500.0);
88 switch (info->status) {
91 ROBOT_LOCK(motion_irc);
92 robot.motion_irc = *instance;
93 ROBOT_UNLOCK(motion_irc);
98 dleft = ((robot.motion_irc.left - instance->left) >> 8) * c;
99 dright = ((instance->right - robot.motion_irc.right) >> 8) * c;
101 dtang = (dleft + dright) / 2.0;
102 dphi = (dright - dleft) / (2.0*ROBOT_ROTATION_RADIUS_M);
104 ROBOT_LOCK(est_pos_odo);
105 double a = robot.est_pos_odo.phi;
106 robot.est_pos_odo.x += dtang*cos(a);
107 robot.est_pos_odo.y += dtang*sin(a);
108 robot.est_pos_odo.phi += dphi;
109 ROBOT_UNLOCK(est_pos_odo);
111 /* locking should not be needed, but... */
112 ROBOT_LOCK(motion_irc);
113 robot.motion_irc = *instance;
114 robot.motion_irc_received = 1;
115 ROBOT_UNLOCK(motion_irc);
117 robot.odometry_works = true;
119 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
122 robot.odometry_works = false;
123 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
124 DBG("ORTE deadline occurred - motion_irc receive\n");
129 void rcv_corr_distances_cb(const ORTERecvInfo *info, void *vinstance,
130 void *recvCallBackParam)
132 struct corr_distances_type *instance =
133 (struct corr_distances_type *)vinstance;
135 switch (info->status) {
137 /* locking should not be needed, but... */
138 ROBOT_LOCK(corr_distances);
139 robot.corr_distances = *instance;
140 ROBOT_UNLOCK(corr_distances);
142 /* wake up motion-control/thread_trajectory_follower */
143 sem_post(&measurement_received);
145 /*FIXME: is following OK? (pecam1) */
146 robot.hw_status[STATUS_UZV] = HW_STATUS_OK;
149 robot.hw_status[STATUS_UZV] = HW_STATUS_FAILED;
155 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
156 void *recvCallBackParam)
158 switch (info->status) {
162 DBG("ORTE deadline occurred - motion_speed receive\n");
167 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
168 void *recvCallBackParam)
170 switch (info->status) {
174 DBG("ORTE deadline occurred - motion_status receive\n");
179 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
180 void *recvCallBackParam)
182 switch (info->status) {
184 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
187 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
188 DBG("ORTE deadline occurred - pwr_voltage receive\n");
193 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
194 void *recvCallBackParam)
196 switch (info->status) {
200 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
205 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
206 void *recvCallBackParam)
208 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
209 static struct robot_cmd_type last_instance;
211 switch (info->status) {
213 /* Stupid way of controlling the robot by
214 * pluggin in and out start connector. */
215 switch (robot.state) {
217 if (instance->start) {
218 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
220 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
222 if (!instance->start) {
223 robot.state = START_PLUGGED_IN;
224 printf("START_PLUGGED_IN\n");
228 case START_PLUGGED_IN:
229 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
230 /* Competition starts when plugged out */
231 if (instance->start) {
232 FSM_SIGNAL(MAIN, EV_START, NULL);
233 robot.state = COMPETITION_STARTED;
238 case COMPETITION_STARTED: {
239 /* Subsequent plug-in stops the robot */
241 if (!instance->start) {
242 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
249 last_instance = *instance;
252 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
253 DBG("ORTE deadline occurred - robot_cmd receive\n");
258 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
259 void *recvCallBackParam)
261 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
263 switch (info->status) {
266 robot.hokuyo = *instance;
267 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
268 ROBOT_UNLOCK(hokuyo);
269 update_map_hokuyo(instance);
273 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
274 //system("killall -9 hokuyo");
275 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
280 void rcv_camera_result_cb(const ORTERecvInfo *info, void *vinstance,
281 void *recvCallBackParam)
283 struct camera_result_type *instance = (struct camera_result_type *)vinstance;
285 switch (info->status) {
287 ROBOT_LOCK(camera_result);
288 robot.game_conf = instance->lot;
289 ROBOT_UNLOCK(camera_result);
290 robot.hw_status[STATUS_CAM] = HW_STATUS_OK;
294 if (robot.orte.camera_control.on) {
295 robot.hw_status[STATUS_CAM] = HW_STATUS_FAILED;
296 //system("killall -9 rozpuk");
299 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
303 /* ----------------------------------------------------------------------
304 * SUBSCRIBER CALLBACKS - EB2008
305 * ---------------------------------------------------------------------- */
307 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
308 void *recvCallBackParam)
310 static unsigned short old_lift_pos=0;
311 static unsigned short old_pusher_pos=0;
312 switch (info->status) {
314 // new data arrived and requested position equals actual position
315 ROBOT_LOCK(lift_cmd);
316 if (robot.orte.actuator_status.lift_pos == robot.orte.lift.pos &&
317 robot.lift_cmd > 0) {
318 FSM_SIGNAL(ACT, EV_LIFT_IN_POS, NULL);
321 ROBOT_UNLOCK(lift_cmd);
322 if (robot.orte.actuator_status.pusher_pos == robot.orte.pusher.pos &&
323 robot.orte.actuator_status.pusher_pos != old_pusher_pos)
324 FSM_SIGNAL(ACT, EV_PUSHER_IN_POS, NULL);
325 if (robot.orte.actuator_status.status & ~LIFT_ENDSW_MASK) {
326 robot.hw_status[STATUS_LFT]=HW_STATUS_WARNING;
328 robot.hw_status[STATUS_LFT]=HW_STATUS_OK;
330 old_lift_pos = robot.orte.actuator_status.lift_pos;
331 old_pusher_pos = robot.orte.actuator_status.pusher_pos;
334 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
335 DBG("ORTE deadline occurred - actuator_status receive\n");
340 void rcv_puck_distance_cb(const ORTERecvInfo *info, void *vinstance,
341 void *recvCallBackParam)
343 switch (info->status) {
345 double old_distance_value = robot.puck_distance;
348 robot.puck_distance = robot.orte.puck_distance.distance;
349 ROBOT_UNLOCK(sharps);
351 if (PUCK_INSIDE(robot.orte.puck_distance.distance) && !PUCK_INSIDE(old_distance_value)) {
352 // signal puck is inside
353 FSM_SIGNAL(ACT, EV_PUCK_INSIDE, NULL);
355 if (PUCK_REACHABLE(robot.orte.puck_distance.distance) && !PUCK_REACHABLE(old_distance_value)) {
356 // signal puck is reachable
357 FSM_SIGNAL(MAIN, EV_PUCK_REACHABLE, NULL);
362 // FIXME F.J. (?) inform display in case of invalid data?
363 // FIXME F.J. (?) limited space on the display...
364 //robot.hw_status[STATUS_ACTUATORS]=HW_STATUS_FAILED;
365 DBG("ORTE deadline occurred - servos receive\n");
370 void rcv_puck_inside_cb(const ORTERecvInfo *info, void *vinstance,
371 void *recvCallBackParam)
373 switch (info->status) {
375 if (robot.use_back_switch) {
376 static bool previous_switch_status = 0;
377 if (robot.orte.puck_inside.status & 0x02) {
378 //FSM_SIGNAL(ACT, EV_PUCK_INSIDE, NULL);
380 /* React on the first switch or when moving backward. */
381 if ((previous_switch_status & 0x02) == 0 ||
382 robot.moves_backward) {
383 FSM_SIGNAL(MOTION, EV_OBSTACLE_BEHIND, NULL);
385 previous_switch_status = robot.orte.puck_inside.status;
389 static bool previous = false;
390 bool switched = ((robot.orte.puck_inside.status & 0x01) != 0);
392 if (switched && !previous) {
393 FSM_SIGNAL(ACT, EV_PUCK_INSIDE, NULL);
398 robot.hw_status[STATUS_CHE]=HW_STATUS_OK;
402 robot.hw_status[STATUS_CHE]=HW_STATUS_FAILED;
403 DBG("ORTE deadline occurred - servos receive\n");
410 static int cmp_double(const void *v1, const void *v2)
412 const double *d1 = v1, *const d2 = v2;
422 int robot_init_orte()
426 robot.orte.strength = 20;
428 rv = robottype_roboorte_init(&robot.orte);
432 /* creating publishers */
433 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
434 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
435 robottype_publisher_est_pos_uzv_create(&robot.orte, send_est_pos_uzv_cb, &robot.orte);
436 robottype_publisher_est_pos_odo_create(&robot.orte, send_est_pos_odo_cb, &robot.orte);
437 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
439 // I didn't know what was the difference between the callback function pointer
440 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
442 // - NULL: message is published only when OrtePublicationSend called
443 // - pointer to empty function: message is published periodically
444 robottype_publisher_lift_create(&robot.orte, send_dummy_cb, &robot.orte);
445 robottype_publisher_pusher_create(&robot.orte, send_dummy_cb, &robot.orte);
446 robottype_publisher_chelae_create(&robot.orte, send_dummy_cb, &robot.orte);
447 robottype_publisher_belts_create(&robot.orte, send_dummy_cb, &robot.orte);
448 robottype_publisher_holder_create(&robot.orte, send_dummy_cb, &robot.orte);
449 robottype_publisher_fsm_main_create(&robot.orte, send_dummy_cb, &robot.orte);
450 robottype_publisher_fsm_act_create(&robot.orte, send_dummy_cb, &robot.orte);
451 robottype_publisher_fsm_motion_create(&robot.orte, send_dummy_cb, &robot.orte);
452 robottype_publisher_camera_control_create(&robot.orte, send_dummy_cb, &robot.orte);
454 /* create generic subscribers */
455 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
456 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
457 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
458 robottype_subscriber_corr_distances_create(&robot.orte, rcv_corr_distances_cb, &robot.orte);
459 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
460 //robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
461 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
462 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
464 /* create subscribers */
465 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
466 //robottype_subscriber_puck_distance_create(&robot.orte, rcv_puck_distance_cb, &robot.orte);
467 robottype_subscriber_puck_inside_create(&robot.orte, rcv_puck_inside_cb, &robot.orte);
468 robottype_subscriber_camera_result_create(&robot.orte, rcv_camera_result_cb, &robot.orte);