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 //robot.hw_status[STATUS_ODO] = HW_STATUS_OK;
125 robot.indep_odometry_works = false;
126 //robot.hw_status[STATUS_ODO] = HW_STATUS_FAILED;
127 DBG("ORTE deadline occurred - odo_data receive\n");
132 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
133 void *recvCallBackParam)
135 struct motion_irc_type *instance = (struct motion_irc_type *)vinstance;
136 double dleft, dright, dtang, dphi;
137 static bool first_run = true;
138 /* spocitat prevodovy pomer */
139 const double n = (double)(28.0 / 1.0);
141 /* vzdalenost na pulz IRC */
142 const double c = (M_PI*2*ROBOT_WHEEL_RADIUS_M) / (n * 4*500.0);
144 switch (info->status) {
147 ROBOT_LOCK(motion_irc);
148 robot.motion_irc = *instance;
149 ROBOT_UNLOCK(motion_irc);
154 dleft = ((robot.motion_irc.left - instance->left) >> 8) * c;
155 dright = ((instance->right - robot.motion_irc.right) >> 8) * c;
157 dtang = (dleft + dright) / 2.0;
158 dphi = (dright - dleft) / (2.0*ROBOT_ROTATION_RADIUS_M);
160 ROBOT_LOCK(est_pos_odo);
161 double a = robot.est_pos_odo.phi;
162 robot.est_pos_odo.x += dtang*cos(a);
163 robot.est_pos_odo.y += dtang*sin(a);
164 robot.est_pos_odo.phi += dphi;
165 ROBOT_UNLOCK(est_pos_odo);
167 /* locking should not be needed, but... */
168 ROBOT_LOCK(motion_irc);
169 robot.motion_irc = *instance;
170 robot.motion_irc_received = 1;
171 ROBOT_UNLOCK(motion_irc);
173 robot.odometry_works = true;
175 robot.hw_status[STATUS_MOTION] = HW_STATUS_OK;
178 robot.odometry_works = false;
179 robot.hw_status[STATUS_MOTION] = HW_STATUS_FAILED;
180 DBG("ORTE deadline occurred - motion_irc receive\n");
185 void rcv_corr_distances_cb(const ORTERecvInfo *info, void *vinstance,
186 void *recvCallBackParam)
188 struct corr_distances_type *instance =
189 (struct corr_distances_type *)vinstance;
191 switch (info->status) {
193 /* locking should not be needed, but... */
194 ROBOT_LOCK(corr_distances);
195 robot.corr_distances = *instance;
196 ROBOT_UNLOCK(corr_distances);
198 /* wake up motion-control/thread_trajectory_follower */
199 sem_post(&measurement_received);
201 /*FIXME: is following OK? (pecam1) */
202 robot.hw_status[STATUS_UZV] = HW_STATUS_OK;
205 robot.hw_status[STATUS_UZV] = HW_STATUS_FAILED;
211 void rcv_motion_speed_cb(const ORTERecvInfo *info, void *vinstance,
212 void *recvCallBackParam)
214 switch (info->status) {
218 DBG("ORTE deadline occurred - motion_speed receive\n");
223 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
224 void *recvCallBackParam)
226 switch (info->status) {
230 DBG("ORTE deadline occurred - motion_status receive\n");
235 void rcv_pwr_voltage_cb(const ORTERecvInfo *info, void *vinstance,
236 void *recvCallBackParam)
238 switch (info->status) {
240 robot.hw_status[STATUS_PWR]=HW_STATUS_OK;
243 robot.hw_status[STATUS_PWR]=HW_STATUS_FAILED;
244 DBG("ORTE deadline occurred - pwr_voltage receive\n");
249 void rcv_pwr_ctrl_cb(const ORTERecvInfo *info, void *vinstance,
250 void *recvCallBackParam)
252 switch (info->status) {
256 DBG("ORTE deadline occurred - pwr_ctrl receive\n");
261 void rcv_robot_cmd_cb(const ORTERecvInfo *info, void *vinstance,
262 void *recvCallBackParam)
264 struct robot_cmd_type *instance = (struct robot_cmd_type *)vinstance;
265 static struct robot_cmd_type last_instance;
267 switch (info->status) {
269 /* Stupid way of controlling the robot by
270 * pluggin in and out start connector. */
271 switch (robot.state) {
273 if (instance->start) {
274 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
276 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
278 if (!instance->start) {
279 robot.state = START_PLUGGED_IN;
280 printf("START_PLUGGED_IN\n");
284 case START_PLUGGED_IN:
285 robot.hw_status[STATUS_STA] = HW_STATUS_OK;
286 /* Competition starts when plugged out */
287 if (instance->start) {
288 FSM_SIGNAL(MAIN, EV_START, NULL);
289 robot.state = COMPETITION_STARTED;
294 case COMPETITION_STARTED: {
295 /* Subsequent plug-in stops the robot */
297 if (!instance->start) {
298 robot.hw_status[STATUS_STA] = HW_STATUS_WARNING;
305 last_instance = *instance;
308 robot.hw_status[STATUS_STA] = HW_STATUS_FAILED;
309 DBG("ORTE deadline occurred - robot_cmd receive\n");
314 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
315 void *recvCallBackParam)
317 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
319 switch (info->status) {
322 robot.hokuyo = *instance;
323 robot.hw_status[STATUS_HOK] = HW_STATUS_OK;
324 ROBOT_UNLOCK(hokuyo);
325 update_map_hokuyo(instance);
329 robot.hw_status[STATUS_HOK] = HW_STATUS_FAILED;
330 //system("killall -9 hokuyo");
331 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
336 // FIXME: this is not up to date (Filip, 2010)
337 void rcv_camera_result_cb(const ORTERecvInfo *info, void *vinstance,
338 void *recvCallBackParam)
340 struct camera_result_type *instance = (struct camera_result_type *)vinstance;
342 switch (info->status) {
344 ROBOT_LOCK(camera_result);
345 robot.game_conf = instance->lot;
346 ROBOT_UNLOCK(camera_result);
347 robot.hw_status[STATUS_CAM] = HW_STATUS_OK;
351 if (robot.orte.camera_control.on) {
352 robot.hw_status[STATUS_CAM] = HW_STATUS_FAILED;
353 //system("killall -9 rozpuk");
356 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
360 /* ----------------------------------------------------------------------
361 * SUBSCRIBER CALLBACKS - EB2008
362 * ---------------------------------------------------------------------- */
364 // FIXME: this is not up to date (Filip, 2010)
365 void rcv_actuator_status_cb(const ORTERecvInfo *info, void *vinstance,
366 void *recvCallBackParam)
368 switch (info->status) {
370 // new data arrived and requested position equals actual position
373 robot.hw_status[STATUS_LFT]=HW_STATUS_FAILED;
374 DBG("ORTE deadline occurred - actuator_status receive\n");
381 static int cmp_double(const void *v1, const void *v2)
383 const double *d1 = v1, *const d2 = v2;
393 int robot_init_orte()
397 robot.orte.strength = 20;
399 rv = robottype_roboorte_init(&robot.orte);
403 /* creating publishers */
404 robottype_publisher_motion_speed_create(&robot.orte, NULL, &robot.orte);
405 robottype_publisher_ref_pos_create(&robot.orte, send_ref_pos_cb, &robot.orte);
406 robottype_publisher_est_pos_odo_create(&robot.orte, send_est_pos_odo_cb, &robot.orte);
407 robottype_publisher_est_pos_indep_odo_create(&robot.orte, send_est_pos_indep_odo_cb, &robot.orte);
408 //???robottype_publisher_pwr_ctrl_create(&robot.orte, NULL, &robot.orte);
410 // I didn't know what was the difference between the callback function pointer
411 // being NULL and being set to pointer to empty send_dummy_cb function. The DIFFERENCE
413 // - NULL: message is published only when OrtePublicationSend called
414 // - pointer to empty function: message is published periodically
415 robottype_publisher_fsm_main_create(&robot.orte, send_dummy_cb, &robot.orte);
416 robottype_publisher_fsm_act_create(&robot.orte, send_dummy_cb, &robot.orte);
417 robottype_publisher_fsm_motion_create(&robot.orte, send_dummy_cb, &robot.orte);
418 robottype_publisher_camera_control_create(&robot.orte, send_dummy_cb, &robot.orte);
420 /* create generic subscribers */
421 robottype_subscriber_odo_data_create(&robot.orte, rcv_odo_data_cb, &robot.orte);
422 robottype_subscriber_motion_irc_create(&robot.orte, rcv_motion_irc_cb, &robot.orte);
423 robottype_subscriber_motion_speed_create(&robot.orte, rcv_motion_speed_cb, &robot.orte);
424 robottype_subscriber_motion_status_create(&robot.orte, rcv_motion_status_cb, &robot.orte);
425 robottype_subscriber_corr_distances_create(&robot.orte, rcv_corr_distances_cb, &robot.orte);
426 robottype_subscriber_pwr_voltage_create(&robot.orte, rcv_pwr_voltage_cb, &robot.orte);
427 //robottype_subscriber_pwr_ctrl_create(&robot.orte, rcv_pwr_ctrl_cb, &robot.orte);
428 robottype_subscriber_robot_cmd_create(&robot.orte, rcv_robot_cmd_cb, &robot.orte);
429 robottype_subscriber_hokuyo_scan_create(&robot.orte, rcv_hokuyo_scan_cb, &robot.orte);
431 /* create subscribers */ // FIXME: these two may be obsolete this year (Filip, 2010)
432 robottype_subscriber_actuator_status_create(&robot.orte, rcv_actuator_status_cb, &robot.orte);
433 robottype_subscriber_camera_result_create(&robot.orte, rcv_camera_result_cb, &robot.orte);