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_odo_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_odo);
59 *instance = robot.est_pos_odo;
60 ROBOT_UNLOCK(est_pos_odo);
63 void send_est_pos_indep_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_indep_odo);
69 *instance = robot.est_pos_indep_odo;
70 ROBOT_UNLOCK(est_pos_indep_odo);
73 void send_dummy_cb(const ORTESendInfo *info, void *vinstance,
74 void *sendCallBackParam)
78 /* ----------------------------------------------------------------------
79 * SUBSCRIBER CALLBACKS - GENERIC
80 * ---------------------------------------------------------------------- */
81 void rcv_odo_data_cb(const ORTERecvInfo *info, void *vinstance,
82 void *recvCallBackParam)
84 struct odo_data_type *instance = (struct odo_data_type *)vinstance;
85 double dleft, dright, dtang, dphi;
86 static bool first_run = true;
87 /* spocitat prevodovy pomer */
88 const double n = (double)(1.0 / 1.0);
90 /* vzdalenost na pulz IRC */
91 const double c = (M_PI*2*ODOMETRY_WHEEL_RADIUS_M) / (n * 4*4096.0);
93 switch (info->status) {
97 robot.odo_data = *instance;
98 ROBOT_UNLOCK(odo_data);
103 dleft = ((robot.odo_data.left - instance->left) >> 8) * c; // TODO >> 8 ?
104 dright = ((instance->right - robot.odo_data.right) >> 8) * c;
106 dtang = (dleft + dright) / 2.0;
107 dphi = (dright - dleft) / (2.0*ODOMETRY_ROTATION_RADIUS_M);
109 ROBOT_LOCK(est_pos_indep_odo);
110 double a = robot.est_pos_indep_odo.phi;
111 robot.est_pos_indep_odo.x += dtang*cos(a);
112 robot.est_pos_indep_odo.y += dtang*sin(a);
113 robot.est_pos_indep_odo.phi += dphi;
114 ROBOT_UNLOCK(est_pos_indep_odo);
116 ROBOT_LOCK(odo_data);
117 robot.odo_data = *instance;
118 ROBOT_UNLOCK(odo_data);
120 robot.indep_odometry_works = true;
122 /* wake up motion-control/thread_trajectory_follower */
123 sem_post(&measurement_received);
125 //robot.hw_status[STATUS_ODO] = HW_STATUS_OK;
128 robot.indep_odometry_works = false;
129 //robot.hw_status[STATUS_ODO] = HW_STATUS_FAILED;
130 DBG("ORTE deadline occurred - odo_data receive\n");
135 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
136 void *recvCallBackParam)
138 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
139 double dleft, dright, dtang, dphi;
140 static bool first_run = true;
141 /* spocitat prevodovy pomer */
142 const double n = (double)(28.0 / 1.0);
144 /* vzdalenost na pulz IRC */
145 const double c = (M_PI*2*ROBOT_WHEEL_RADIUS_M) / (n * 4*500.0);
147 switch (info->status) {
150 ROBOT_LOCK(motion_irc);
151 robot.motion_irc = *instance;
152 ROBOT_UNLOCK(motion_irc);
157 dleft = ((robot.motion_irc.left - instance->left) >> 8) * c;
158 dright = ((instance->right - robot.motion_irc.right) >> 8) * c;
160 dtang = (dleft + dright) / 2.0;
161 dphi = (dright - dleft) / (2.0*ROBOT_ROTATION_RADIUS_M);
163 ROBOT_LOCK(est_pos_odo);
164 double a = robot.est_pos_odo.phi;
165 robot.est_pos_odo.x += dtang*cos(a);
166 robot.est_pos_odo.y += dtang*sin(a);
167 robot.est_pos_odo.phi += dphi;
168 ROBOT_UNLOCK(est_pos_odo);
170 /* locking should not be needed, but... */
171 ROBOT_LOCK(motion_irc);
172 robot.motion_irc = *instance;
173 robot.motion_irc_received = 1;
174 ROBOT_UNLOCK(motion_irc);
176 robot.odometry_works = true;
178 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
181 robot.odometry_works = false;
182 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
183 DBG("ORTE deadline occurred - motion_irc receive\n");
188 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
189 void *recvCallBackParam)
191 switch (info->status) {
195 DBG("ORTE deadline occurred - motion_speed receive\n");
200 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
201 void *recvCallBackParam)
203 switch (info->status) {
207 DBG("ORTE deadline occurred - motion_status receive\n");
212 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
213 void *recvCallBackParam)
215 switch (info->status) {
217 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
220 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
221 DBG("ORTE deadline occurred - pwr_voltage receive\n");
226 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
227 void *recvCallBackParam)
229 switch (info->status) {
233 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
238 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
239 void *recvCallBackParam)
241 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
242 static struct robot_cmd_type last_instance;
244 switch (info->status) {
246 /* Stupid way of controlling the robot by
247 * pluggin in and out start connector. */
248 switch (robot.state) {
250 if (instance->start) {
251 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
253 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
255 if (!instance->start) {
256 robot.state = START_PLUGGED_IN;
257 printf("START_PLUGGED_IN\n");
261 case START_PLUGGED_IN:
262 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
263 /* Competition starts when plugged out */
264 if (instance->start) {
265 FSM_SIGNAL(MAIN, EV_START, NULL);
266 robot.state = COMPETITION_STARTED;
271 case COMPETITION_STARTED: {
272 /* Subsequent plug-in stops the robot */
274 if (!instance->start) {
275 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
282 last_instance = *instance;
285 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
286 DBG("ORTE deadline occurred - robot_cmd receive\n");
291 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
292 void *recvCallBackParam)
294 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
296 switch (info->status) {
299 robot.hokuyo = *instance;
300 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
301 ROBOT_UNLOCK(hokuyo);
302 update_map_hokuyo(instance);
306 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
307 //system("killall -9 hokuyo");
308 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
313 // FIXME: this is not up to date (Filip, 2010)
314 void rcv_camera_result_cb(const ORTERecvInfo *info, void *vinstance,
315 void *recvCallBackParam)
317 struct camera_result_type *instance = (struct camera_result_type *)vinstance;
319 switch (info->status) {
321 ROBOT_LOCK(camera_result);
322 robot.game_conf = instance->lot;
323 ROBOT_UNLOCK(camera_result);
324 robot.hw_status[STATUS_CAM] = HW_STATUS_OK;
328 if (robot.orte.camera_control.on) {
329 robot.hw_status[STATUS_CAM] = HW_STATUS_FAILED;
330 //system("killall -9 rozpuk");
333 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
337 /* ----------------------------------------------------------------------
338 * SUBSCRIBER CALLBACKS - EB2008
339 * ---------------------------------------------------------------------- */
341 // FIXME: this is not up to date (Filip, 2010)
342 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
343 void *recvCallBackParam)
345 switch (info->status) {
347 // new data arrived and requested position equals actual position
350 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
351 DBG("ORTE deadline occurred - actuator_status receive\n");
358 static int cmp_double(const void *v1, const void *v2)
360 const double *d1 = v1, *const d2 = v2;
370 int robot_init_orte()
374 robot.orte.strength = 20;
376 rv = robottype_roboorte_init(&robot.orte);
380 /* creating publishers */
381 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
382 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
383 robottype_publisher_est_pos_odo_create(&robot.orte, send_est_pos_odo_cb, &robot.orte);
384 robottype_publisher_est_pos_indep_odo_create(&robot.orte, send_est_pos_indep_odo_cb, &robot.orte);
385 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
387 // I didn't know what was the difference between the callback function pointer
388 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
390 // - NULL: message is published only when OrtePublicationSend called
391 // - pointer to empty function: message is published periodically
392 robottype_publisher_fsm_main_create(&robot.orte, send_dummy_cb, &robot.orte);
393 robottype_publisher_fsm_act_create(&robot.orte, send_dummy_cb, &robot.orte);
394 robottype_publisher_fsm_motion_create(&robot.orte, send_dummy_cb, &robot.orte);
395 robottype_publisher_camera_control_create(&robot.orte, send_dummy_cb, &robot.orte);
397 /* create generic subscribers */
398 robottype_subscriber_odo_data_create(&robot.orte, rcv_odo_data_cb, &robot.orte);
399 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
400 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
401 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
402 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
403 //robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
404 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
405 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
407 /* create subscribers */ // FIXME: these two may be obsolete this year (Filip, 2010)
408 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
409 robottype_subscriber_camera_result_create(&robot.orte, rcv_camera_result_cb, &robot.orte);