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>
16 #include <movehelper.h>
19 #include <laser-nav.h>
20 #include "map_handling.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 ref_pos_type *instance = (struct ref_pos_type *)vinstance;
43 *instance = robot.ref_pos;
44 ROBOT_UNLOCK(ref_pos);
47 void send_est_pos_cb(const ORTESendInfo *info, void *vinstance,
48 void *sendCallBackParam)
50 struct est_pos_type *instance = (struct est_pos_type *)vinstance;
53 *instance = robot.est_pos;
54 ROBOT_UNLOCK(est_pos);
57 void send_dummy_cb(const ORTESendInfo *info, void *vinstance,
58 void *sendCallBackParam)
62 /* ----------------------------------------------------------------------
63 * SUBSCRIBER CALLBACKS - GENERIC
64 * ---------------------------------------------------------------------- */
66 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
67 void *recvCallBackParam)
69 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
71 switch (info->status) {
73 /* locking should not be needed, but... */
74 ROBOT_LOCK(motion_irc);
75 robot.motion_irc = *instance;
76 robot.motion_irc_received = 1;
77 ROBOT_UNLOCK(motion_irc);
79 /* FSM_SIGNAL(LOC, EV_ODO_RECEIVED, odo); */
80 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
83 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
84 DBG("ORTE deadline occurred - motion_irc receive\n");
89 void rcv_corr_distances_cb(const ORTERecvInfo *info, void *vinstance,
90 void *recvCallBackParam)
92 struct corr_distances_type *instance =
93 (struct corr_distances_type *)vinstance;
95 switch (info->status) {
97 /* locking should not be needed, but... */
98 ROBOT_LOCK(corr_distances);
99 robot.corr_distances = *instance;
100 ROBOT_UNLOCK(corr_distances);
102 /* wake up motion-control/thread_trajectory_follower */
103 sem_post(&measurement_received);
105 /*FIXME: is following OK? (pecam1) */
106 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
109 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
110 DBG("ORTE deadline occurred - corr_distances receive\n");
115 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
116 void *recvCallBackParam)
118 switch (info->status) {
122 DBG("ORTE deadline occurred - motion_speed receive\n");
127 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
128 void *recvCallBackParam)
130 switch (info->status) {
134 DBG("ORTE deadline occurred - motion_status receive\n");
139 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
140 void *recvCallBackParam)
142 switch (info->status) {
144 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
147 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
148 DBG("ORTE deadline occurred - pwr_voltage receive\n");
153 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
154 void *recvCallBackParam)
156 switch (info->status) {
160 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
165 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
166 void *recvCallBackParam)
168 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
169 static struct robot_cmd_type last_instance;
170 enum robot_state state;
172 switch (info->status) {
174 /* Stupid way of controlling the robot by
175 * pluggin in and out start connector. */
176 if (instance->start == last_instance.start)
182 printf("in state=%d \n", state);
186 /* On first plug-in laser is tarted */
189 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
190 // FSM_SIGNAL(MAIN, EV_LASER_POWER, NULL);
191 state = LASER_STARTED;
195 /* Competition starts when plugged out */
196 if (!instance->start)
198 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
199 FSM_SIGNAL(MAIN, EV_START, NULL);
200 state = COMPETITION_STARTED;
203 case COMPETITION_STARTED:
204 /* Subsequent plug-in stops the robot */
205 if (!instance->start) {
210 last_instance = *instance;
211 printf("out state=%d \n", state);
217 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
218 DBG("ORTE deadline occurred - robot_cmd receive\n");
223 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
224 void *recvCallBackParam)
226 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
228 switch (info->status) {
231 robot.hokuyo = *instance;
232 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
233 ROBOT_UNLOCK(hokuyo);
234 update_map_hokuyo(instance);
238 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
239 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
243 /* ----------------------------------------------------------------------
244 * SUBSCRIBER CALLBACKS - EB2008
245 * ---------------------------------------------------------------------- */
247 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
248 void *recvCallBackParam)
250 switch (info->status) {
252 // requested position equals actual position...
253 if (robot.orte.actuator_status.lift_pos == robot.orte.lift.pos)
254 FSM_SIGNAL(ACT, EV_LIFT_IN_POS, NULL);
255 if (robot.orte.actuator_status.pusher_pos == robot.orte.pusher.pos)
256 FSM_SIGNAL(ACT, EV_PUSHER_IN_POS, NULL);
257 if (robot.orte.actuator_status.status == 0) {
258 robot.hw_status[STATUS_LFT]=HW_STATUS_OK;
260 robot.hw_status[STATUS_LFT]=HW_STATUS_WARNING;
264 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
265 DBG("ORTE deadline occurred - actuator_status receive\n");
270 void rcv_puck_distance_cb(const ORTERecvInfo *info, void *vinstance,
271 void *recvCallBackParam)
273 switch (info->status) {
275 double old_distance_value = robot.puck_distance;
278 robot.puck_distance = robot.orte.puck_distance.distance;
279 ROBOT_UNLOCK(sharps);
281 if (PUCK_INSIDE(robot.orte.puck_distance.distance) && !PUCK_INSIDE(old_distance_value)) {
282 // signal puck is inside
283 FSM_SIGNAL(ACT, EV_PUCK_INSIDE, NULL);
285 if (PUCK_REACHABLE(robot.orte.puck_distance.distance) && !PUCK_REACHABLE(old_distance_value)) {
286 // signal puck is reachable
287 FSM_SIGNAL(MAIN, EV_PUCK_REACHABLE, NULL);
292 // FIXME F.J. (?) inform display in case of invalid data?
293 // FIXME F.J. (?) limited space on the display...
294 //robot.hw_status[STATUS_ACTUATORS]=HW_STATUS_FAILED;
295 DBG("ORTE deadline occurred - servos receive\n");
301 void rcv_cmu_cb(const ORTERecvInfo *info, void *vinstance,
302 void *recvCallBackParam)
304 struct cmu_type *instance = (struct cmu_type *)vinstance;
305 static enum ball_color last_color = NO_BALL;
306 static unsigned char first = 1;
308 switch (info->status) {
311 robot.cmu = *instance;
314 last_color = robot.cmu.color;
317 if (robot.cmu.color != NO_BALL) {
318 if (last_color != robot.cmu.color) {
319 last_color = robot.cmu.color;
320 //FSM_SIGNAL(MAIN, EV_BALL_INSIDE, NULL);
323 robot.hw_status[STATUS_CMU] = HW_STATUS_OK;
327 robot.hw_status[STATUS_CMU] = HW_STATUS_FAILED;
328 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
336 static int cmp_double(const void *v1, const void *v2)
338 const double *d1 = v1, *const d2 = v2;
347 int robot_init_orte()
351 robot.orte.strength = 20;
353 rv = robottype_roboorte_init(&robot.orte);
357 /* creating publishers */
358 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
359 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
360 robottype_publisher_est_pos_create(&robot.orte, send_est_pos_cb, &robot.orte);
361 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
363 // I didn't know what was the difference between the callback function pointer
364 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
366 // - NULL: message is published only when OrtePublicationSend called
367 // - pointer to empty function: message is published periodically
368 robottype_publisher_lift_create(&robot.orte, send_dummy_cb, &robot.orte);
369 robottype_publisher_pusher_create(&robot.orte, send_dummy_cb, &robot.orte);
370 robottype_publisher_chelae_create(&robot.orte, send_dummy_cb, &robot.orte);
371 robottype_publisher_belts_create(&robot.orte, send_dummy_cb, &robot.orte);
372 robottype_publisher_holder_create(&robot.orte, send_dummy_cb, &robot.orte);
373 robottype_publisher_fsm_main_create(&robot.orte, send_dummy_cb, &robot.orte);
374 robottype_publisher_fsm_act_create(&robot.orte, send_dummy_cb, &robot.orte);
375 robottype_publisher_fsm_motion_create(&robot.orte, send_dummy_cb, &robot.orte);
377 /* create generic subscribers */
378 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
379 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
380 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
381 robottype_subscriber_corr_distances_create(&robot.orte, rcv_corr_distances_cb, &robot.orte);
382 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
383 robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
384 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
385 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
387 /* create subscribers */
388 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
389 robottype_subscriber_puck_distance_create(&robot.orte, rcv_puck_distance_cb, &robot.orte);
390 //robottype_subscriber_cmu_create(&robot.orte, rcv_cmu_cb, &robot.orte);