5 * @brief Display-ORTE bridge
7 * Copyright: (c) 2010 CTU Dragons
8 * CTU FEE - Department of Control Engineering
15 #include <roboorte_robottype.h>
16 //#include <pthread.h>
26 struct sercom_data* sercom;
29 static void sig_handler(int sig)
36 * Subtract the `struct timespec' values X and Y,
37 * storing the result in RESULT (result = x - y).
38 * Return 1 if the difference is negative, otherwise 0.
40 int timespec_subtract (struct timespec *result,
44 /* Perform the carry for the later subtraction by updating Y. */
45 if (x->tv_nsec < y->tv_nsec) {
46 int num_sec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
47 y->tv_nsec -= 1000000000 * num_sec;
50 if (x->tv_nsec - y->tv_nsec > 1000000000) {
51 int num_sec = (x->tv_nsec - y->tv_nsec) / 1000000000;
52 y->tv_nsec += 1000000000 * num_sec;
56 /* Compute the time remaining to wait.
57 `tv_nsec' is certainly positive. */
58 result->tv_sec = x->tv_sec - y->tv_sec;
59 result->tv_nsec = x->tv_nsec - y->tv_nsec;
61 /* Return 1 if result is negative. */
62 return x->tv_sec < y->tv_sec;
65 bool miliseconds_elapsed_since(struct timespec *t, unsigned miliseconds)
67 struct timespec now, diff;
68 unsigned long long elapsed;
70 if (t->tv_sec == 0 && t->tv_nsec == 0)
71 return true; /* Always elapsed after program start */
73 clock_gettime(CLOCK_MONOTONIC, &now);
74 timespec_subtract(&diff, &now, t);
75 elapsed = diff.tv_sec * 1000 + diff.tv_nsec/1000000;
76 return elapsed > miliseconds;
81 void rcv_pwr_voltage_cb (const ORTERecvInfo *info, void *vinstance,
82 void *recvCallBackParam)
84 UDE_hw_status_t status = STATUS_FAILED;
85 static UDE_hw_status_t last_status;
86 static struct timespec last_sent;
87 struct robottype_orte_data *orte_data = (struct robottype_orte_data *)recvCallBackParam;
88 switch (info->status) {
90 uoled_display_voltage(orte_data->pwr_voltage.voltage33,orte_data->pwr_voltage.voltage50,
91 orte_data->pwr_voltage.voltage80, orte_data->pwr_voltage.voltageBAT);
95 status = STATUS_FAILED;
98 if (status != last_status ||
99 miliseconds_elapsed_since(&last_sent, 1000)) {
100 uoled_display_status(PWR, status);
101 clock_gettime(CLOCK_MONOTONIC, &last_sent);
103 last_status = status;
106 void rcv_odo_data_cb(const ORTERecvInfo *info, void *vinstance,
107 void *recvCallBackParam)
109 UDE_hw_status_t status = STATUS_FAILED;
110 static UDE_hw_status_t last_status;
111 static struct timespec last_sent;
112 //struct odo_data_type *instance = (struct odo_data_type *)vinstance;
113 switch (info->status) {
118 status = STATUS_FAILED;
121 /* Neni potreba aktualizovat stav na displeji 25x za sekundu */
122 if (status != last_status ||
123 miliseconds_elapsed_since(&last_sent, 1000)) {
124 uoled_display_status(ODO, status);
125 clock_gettime(CLOCK_MONOTONIC, &last_sent);
127 last_status = status;
130 void rcv_motion_irc_cb(const ORTERecvInfo *info, void *vinstance,
131 void *recvCallBackParam)
133 UDE_hw_status_t status = STATUS_FAILED;
134 static UDE_hw_status_t last_status;
135 static struct timespec last_sent;
136 switch (info->status) {
141 status = STATUS_FAILED;
144 /* Neni potreba aktualizovat stav na displeji 25x za sekundu */
145 if (status != last_status ||
146 miliseconds_elapsed_since(&last_sent, 1000)) {
147 uoled_display_status(MOT, status);
148 clock_gettime(CLOCK_MONOTONIC, &last_sent);
150 last_status = status;
153 void rcv_motion_status_cb(const ORTERecvInfo *info, void *vinstance,
154 void *recvCallBackParam)
156 struct motion_status_type *m = (struct motion_status_type *)vinstance;
157 UDE_hw_status_t status = STATUS_FAILED;
158 static UDE_hw_status_t last_status;
159 static struct timespec last_sent;
160 switch (info->status) {
162 if (m->err_left == 0 && m->err_right == 0)
165 status = STATUS_WARNING;
168 status = STATUS_FAILED;
171 /* Neni potreba aktualizovat stav na displeji 25x za sekundu */
172 if (status != last_status ||
173 miliseconds_elapsed_since(&last_sent, 1000)) {
174 uoled_display_status(MOT, status);
175 clock_gettime(CLOCK_MONOTONIC, &last_sent);
177 last_status = status;
180 void rcv_camera_result_cb(const ORTERecvInfo *info, void *vinstance,
181 void *recvCallBackParam)
183 UDE_hw_status_t status = STATUS_FAILED;
184 static UDE_hw_status_t last_status;
185 static struct timespec last_sent;
186 //struct camera_result_type *instance = (struct camera_result_type *)vinstance;
187 switch (info->status) {
192 status = STATUS_FAILED;
195 if (status != last_status ||
196 miliseconds_elapsed_since(&last_sent, 1000)) {
197 uoled_display_status(CAM, status);
198 clock_gettime(CLOCK_MONOTONIC, &last_sent);
200 last_status = status;
203 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
204 void *recvCallBackParam)
206 UDE_hw_status_t status = STATUS_FAILED;
207 static UDE_hw_status_t last_status;
208 static struct timespec last_sent;
209 //struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
210 switch (info->status) {
215 status = STATUS_FAILED;
218 if (status != last_status ||
219 miliseconds_elapsed_since(&last_sent, 1000)) {
220 uoled_display_status(HOK, status);
221 clock_gettime(CLOCK_MONOTONIC, &last_sent);
223 last_status = status;
226 void rcv_est_pos_best_cb (const ORTERecvInfo *info, void *vinstance,
227 void *recvCallBackParam)
229 UDE_hw_status_t status = STATUS_FAILED;
230 static UDE_hw_status_t last_status;
231 static struct timespec last_sent;
232 struct robottype_orte_data *orte_data = (struct robottype_orte_data *)recvCallBackParam;
233 switch (info->status) {
238 status = STATUS_FAILED;
241 if (status != last_status ||
242 miliseconds_elapsed_since(&last_sent, 100)) {
243 uoled_display_status(APP, status);
244 if (status == STATUS_OK)
245 uoled_display_position(orte_data->est_pos_best.x, orte_data->est_pos_best.y, orte_data->est_pos_best.phi);
246 clock_gettime(CLOCK_MONOTONIC, &last_sent);
248 last_status = status;
251 void rcv_fsm_main_cb(const ORTERecvInfo *info, void *vinstance,
252 void *recvCallBackParam)
254 char status[MGS_LENGTH_DISPLAY_SM];
255 static char last_status[MGS_LENGTH_DISPLAY_SM];
256 static struct timespec last_sent;
257 struct fsm_state_type *fsm_state = (struct fsm_state_type *)vinstance;
258 switch (info->status) {
260 strncpy(status, fsm_state->state_name, MGS_LENGTH_DISPLAY_SM);
261 status[MGS_LENGTH_DISPLAY_SM-1]='\0';
262 //uoled_display_fsm(FSM_MAIN, fsm_state->state_name);
266 //uoled_display_fsm(FSM_MAIN, "?");
269 if (strcmp(status,last_status) != 0 ||
270 miliseconds_elapsed_since(&last_sent, 1000)) {
271 uoled_display_fsm(FSM_MAIN, status);
272 clock_gettime(CLOCK_MONOTONIC, &last_sent);
274 strncpy(last_status,status,MGS_LENGTH_DISPLAY_SM);
277 void rcv_fsm_act_cb(const ORTERecvInfo *info, void *vinstance,
278 void *recvCallBackParam)
280 char status[MGS_LENGTH_DISPLAY_SM];
281 static char last_status[MGS_LENGTH_DISPLAY_SM];
282 static struct timespec last_sent;
283 struct fsm_state_type *fsm_state = (struct fsm_state_type *)vinstance;
284 switch (info->status) {
286 strncpy(status, fsm_state->state_name, MGS_LENGTH_DISPLAY_SM);
287 status[MGS_LENGTH_DISPLAY_SM-1]='\0';
293 if (strcmp(status,last_status) != 0 ||
294 miliseconds_elapsed_since(&last_sent, 1000)) {
295 uoled_display_fsm(FSM_ACT, status);
296 clock_gettime(CLOCK_MONOTONIC, &last_sent);
298 strncpy(last_status,status,MGS_LENGTH_DISPLAY_SM);
301 void rcv_fsm_motion_cb(const ORTERecvInfo *info, void *vinstance,
302 void *recvCallBackParam)
304 char status[MGS_LENGTH_DISPLAY_SM];
305 static char last_status[MGS_LENGTH_DISPLAY_SM];
306 static struct timespec last_sent;
307 struct fsm_state_type *fsm_state = (struct fsm_state_type *)vinstance;
308 switch (info->status) {
310 strncpy(status, fsm_state->state_name, MGS_LENGTH_DISPLAY_SM);
311 status[MGS_LENGTH_DISPLAY_SM-1]='\0';
317 if (strcmp(status,last_status) != 0 ||
318 miliseconds_elapsed_since(&last_sent, 1000)) {
319 uoled_display_fsm(FSM_MOVE, status);
320 clock_gettime(CLOCK_MONOTONIC, &last_sent);
322 strncpy(last_status,status,MGS_LENGTH_DISPLAY_SM);
328 int main(int argc, char *argv[])
330 //fd_set read_fd_set;
331 //struct timeval timeout;
335 struct robottype_orte_data orte;
338 signal(SIGINT, sig_handler);
339 signal(SIGTERM, sig_handler);
341 //struct can_frame frame;
342 tty = getenv("DISPLAY_TTY");
345 printf("displayd: enviroment variable 'DISPLAY_TTY' was not set, using default value '%s'.\n", tty);
348 sercom = uoled_sercom_init(tty, NULL);
349 if (strcmp(tty, "/dev/null") != 0 && sercom) {
351 printf("displayd: init serial communication OK\n");
353 fprintf(stderr, "displayd: init serial communication failed\n");
355 /* Sleep in order to that not be respawn too fast by init */
363 /* orte initialization */
364 if(robottype_roboorte_init(&orte)) {
365 fprintf(stderr, "displayd: Roboorte initialization failed! Exiting...\n");
367 /* Sleep in order to that not be respawn too fast by init */
373 printf("displayd: Roboorte OK\n");
375 /* creating publishers */
376 //robottype_publisher_pwr_voltage_create(&orte, NULL, NULL);
377 //robottype_publisher_motion_status_create(&orte, NULL, NULL);
378 //robottype_publisher_odo_data_create(&orte, NULL, NULL);
379 //robottype_publisher_motion_irc_create(&orte, NULL, NULL);
380 //robottype_publisher_robot_cmd_create(&orte, NULL, NULL);
381 //robottype_publisher_corr_trig_create(&orte, NULL, NULL);
382 //robottype_publisher_corr_distances_create(&orte, NULL, NULL);
383 //robottype_publisher_actuator_status_create(&orte, NULL, NULL);
384 //printf("Publishers OK\n");
386 /* creating subscribers */
387 robottype_subscriber_odo_data_create(&orte, rcv_odo_data_cb, &orte);
388 robottype_subscriber_motion_status_create(&orte, rcv_motion_status_cb, NULL);
389 //robottype_subscriber_motion_irc_create(&orte, rcv_motion_irc_cb, &orte);
390 robottype_subscriber_pwr_voltage_create(&orte, rcv_pwr_voltage_cb, &orte);
391 robottype_subscriber_est_pos_best_create(&orte, rcv_est_pos_best_cb, &orte);
392 //robottype_subscriber_pwr_alert_create(&orte, rcv_pwr_alert_cb, &orte);
393 //robottype_subscriber_motion_speed_create(&orte, rcv_motion_speed_cb, &orte);
394 //robottype_subscriber_can_msg_create(&orte, rcv_can_msg_cb, &orte);
395 robottype_subscriber_hokuyo_scan_create(&orte, rcv_hokuyo_scan_cb, &orte);
396 robottype_subscriber_camera_result_create(&orte, rcv_camera_result_cb, &orte);
397 robottype_subscriber_fsm_main_create(&orte, rcv_fsm_main_cb, &orte);
398 robottype_subscriber_fsm_act_create(&orte, rcv_fsm_act_cb, &orte);
399 robottype_subscriber_fsm_motion_create(&orte, rcv_fsm_motion_cb, &orte);
401 printf("displayd: subscribers created OK\n");
404 UDE_recieve_cmd_t rcmd;
405 struct pollfd pfd[1] = {{
413 if (strcmp(tty, "/dev/null") != 0) {
414 ret = poll(pfd, 1, 500/*ms*/);
416 rcmd = uoled_recieve_cmd();
417 orte.display_cmd.command=rcmd;
419 ORTEPublicationSend(orte.publication_display_cmd);
420 printf("displayd: publishing command recieved from display [ 0x%2x ]\n", rcmd);
425 usleep(500/*ms*/*1000);
429 uoled_display_alive();
433 printf("displayd: closing serial communication...\n");
434 uoled_sercom_close();
435 // printf("displayd: destroying display_cmd publisher...\n");
436 // robottype_publisher_display_cmd_destroy(&orte);
437 printf("displayd: destroying orte instance...\n");
438 robottype_roboorte_destroy(&orte);
440 printf("displayd: finished!\n");