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 extern sem_t measurement_received;
27 /* ----------------------------------------------------------------------
28 * PUBLISHER CALLBACKS - GENERIC
29 * ---------------------------------------------------------------------- */
31 void send_ref_pos_cb(const ORTESendInfo *info, void *vinstance,
32 void *sendCallBackParam)
34 struct ref_pos_type *instance = (struct ref_pos_type *)vinstance;
37 *instance = robot.ref_pos;
38 ROBOT_UNLOCK(ref_pos);
41 void send_est_pos_cb(const ORTESendInfo *info, void *vinstance,
42 void *sendCallBackParam)
44 struct est_pos_type *instance = (struct est_pos_type *)vinstance;
47 *instance = robot.est_pos;
48 ROBOT_UNLOCK(est_pos);
51 void send_dummy_cb(const ORTESendInfo *info, void *vinstance,
52 void *sendCallBackParam)
56 /* ----------------------------------------------------------------------
57 * SUBSCRIBER CALLBACKS - GENERIC
58 * ---------------------------------------------------------------------- */
60 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
61 void *recvCallBackParam)
63 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
65 switch (info->status) {
67 /* locking should not be needed, but... */
68 ROBOT_LOCK(motion_irc);
69 robot.motion_irc = *instance;
70 robot.motion_irc_received = 1;
71 ROBOT_UNLOCK(motion_irc);
73 /* FSM_SIGNAL(LOC, EV_ODO_RECEIVED, odo); */
74 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
77 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
78 DBG("ORTE deadline occurred - motion_irc receive\n");
83 void rcv_corr_distances_cb(const ORTERecvInfo *info, void *vinstance,
84 void *recvCallBackParam)
86 struct corr_distances_type *instance =
87 (struct corr_distances_type *)vinstance;
89 switch (info->status) {
91 /* locking should not be needed, but... */
92 ROBOT_LOCK(corr_distances);
93 robot.corr_distances = *instance;
94 ROBOT_UNLOCK(corr_distances);
96 /* wake up motion-control/thread_trajectory_follower */
97 sem_post(&measurement_received);
99 /*FIXME: is following OK? (pecam1) */
100 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
103 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
104 DBG("ORTE deadline occurred - corr_distances receive\n");
109 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
110 void *recvCallBackParam)
112 switch (info->status) {
116 DBG("ORTE deadline occurred - motion_speed receive\n");
121 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
122 void *recvCallBackParam)
124 switch (info->status) {
128 DBG("ORTE deadline occurred - motion_status receive\n");
133 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
134 void *recvCallBackParam)
136 switch (info->status) {
138 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
141 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
142 DBG("ORTE deadline occurred - pwr_voltage receive\n");
147 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
148 void *recvCallBackParam)
150 switch (info->status) {
154 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
159 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
160 void *recvCallBackParam)
162 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
163 static struct robot_cmd_type last_instance;
164 enum robot_state state;
166 switch (info->status) {
168 /* Stupid way of controlling the robot by
169 * pluggin in and out start connector. */
170 if (instance->start == last_instance.start)
176 printf("in state=%d \n", state);
180 /* On first plug-in laser is tarted */
183 robot.hw_status[STATUS_STA] = HW_STATUS_WARN;
184 // FSM_SIGNAL(MAIN, EV_LASER_POWER, NULL);
185 state = LASER_STARTED;
189 /* Competition starts when plugged out */
190 if (!instance->start)
192 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
193 FSM_SIGNAL(MAIN, EV_START, NULL);
194 state = COMPETITION_STARTED;
197 case COMPETITION_STARTED:
198 /* Subsequent plug-in stops the robot */
199 if (!instance->start) {
204 last_instance = *instance;
205 printf("out state=%d \n", state);
211 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
212 DBG("ORTE deadline occurred - robot_cmd receive\n");
217 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
218 void *recvCallBackParam)
220 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
222 switch (info->status) {
225 robot.hokuyo = *instance;
226 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
227 ROBOT_UNLOCK(hokuyo);
228 update_map_hokuyo(instance);
232 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
233 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
237 /* ----------------------------------------------------------------------
238 * SUBSCRIBER CALLBACKS - EB2008
239 * ---------------------------------------------------------------------- */
241 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
242 void *recvCallBackParam)
244 switch (info->status) {
246 if (robot.orte.actuator_status.status == 0) {
247 robot.hw_status[STATUS_LFT]=HW_STATUS_OK;
250 robot.hw_status[STATUS_LFT]=HW_STATUS_WARNING;
253 //FSM_SIGNAL(ACT, STATUS_RCVD, NULL);
256 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
258 DBG("ORTE deadline occurred - actuator_status receive\n");
263 void rcv_puck_distance_cb(const ORTERecvInfo *info, void *vinstance,
264 void *recvCallBackParam)
266 switch (info->status) {
268 //printf("Sharp distance: %f\n", robot.orte.puck_distance.distance);
269 if(robot.orte.puck_distance.distance <= 0.055) {
270 FSM_SIGNAL(ACT, EV_PUCK_INSIDE, NULL);
272 if(robot.orte.puck_distance.distance < 0.13 && robot.orte.puck_distance.distance > 0.055) {
273 FSM_SIGNAL(ACT, EV_PUCK_REACHABLE, NULL);
277 // FIXME F.J. (?) inform display in case of invalid data?
278 // FIXME F.J. (?) limited space on the display...
279 //robot.hw_status[STATUS_ACTUATORS]=HW_STATUS_FAILED;
280 DBG("ORTE deadline occurred - servos receive\n");
286 void rcv_cmu_cb(const ORTERecvInfo *info, void *vinstance,
287 void *recvCallBackParam)
289 struct cmu_type *instance = (struct cmu_type *)vinstance;
290 static enum ball_color last_color = NO_BALL;
291 static unsigned char first = 1;
293 switch (info->status) {
296 robot.cmu = *instance;
299 last_color = robot.cmu.color;
302 if (robot.cmu.color != NO_BALL) {
303 if (last_color != robot.cmu.color) {
304 last_color = robot.cmu.color;
305 //FSM_SIGNAL(MAIN, EV_BALL_INSIDE, NULL);
308 robot.hw_status[STATUS_CMU] = HW_STATUS_OK;
312 robot.hw_status[STATUS_CMU] = HW_STATUS_FAILED;
313 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
321 static int cmp_double(const void *v1, const void *v2)
323 const double *d1 = v1, *const d2 = v2;
332 int robot_init_orte()
336 robot.orte.strength = 20;
338 rv = robottype_roboorte_init(&robot.orte);
342 /* creating publishers */
343 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
344 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
345 robottype_publisher_est_pos_create(&robot.orte, send_est_pos_cb, &robot.orte);
346 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
348 // I didn't know what was the difference between the callback function pointer
349 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
351 // - NULL: message is published only when OrtePublicationSend called
352 // - pointer to empty function: message is published periodically
353 robottype_publisher_lift_create(&robot.orte, send_dummy_cb, &robot.orte);
354 robottype_publisher_pusher_create(&robot.orte, send_dummy_cb, &robot.orte);
355 robottype_publisher_chelae_create(&robot.orte, send_dummy_cb, &robot.orte);
356 robottype_publisher_belts_create(&robot.orte, send_dummy_cb, &robot.orte);
357 robottype_publisher_holder_create(&robot.orte, send_dummy_cb, &robot.orte);
358 robottype_publisher_hokuyo_pitch_create(&robot.orte, send_dummy_cb, &robot.orte);
360 /* create generic subscribers */
361 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
362 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
363 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
364 robottype_subscriber_corr_distances_create(&robot.orte, rcv_corr_distances_cb, &robot.orte);
365 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
366 robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
367 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
368 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
370 /* create subscribers */
371 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
372 robottype_subscriber_puck_distance_create(&robot.orte, rcv_puck_distance_cb, &robot.orte);
373 //robottype_subscriber_cmu_create(&robot.orte, rcv_cmu_cb, &robot.orte);