2 #include <movehelper.h>
8 #include <robot_orte.h>
13 #include "map_handling.h"
20 /* Subtract the `struct timespec' values X and Y,
21 storing the result in RESULT (result = x - y).
22 Return 1 if the difference is negative, otherwise 0. */
24 int timespec_subtract (timespec &result, timespec &x, timespec &y) {
25 /* Perform the carry for the later subtraction by updating Y. */
26 if (x.tv_nsec < y.tv_nsec) {
27 int num_sec = (y.tv_nsec - x.tv_nsec) / 1000000000 + 1;
28 y.tv_nsec -= 1000000000 * num_sec;
31 if (x.tv_nsec - y.tv_nsec > 1000000000) {
32 int num_sec = (x.tv_nsec - y.tv_nsec) / 1000000000;
33 y.tv_nsec += 1000000000 * num_sec;
37 /* Compute the time remaining to wait.
38 `tv_nsec' is certainly positive. */
39 result.tv_sec = x.tv_sec - y.tv_sec;
40 result.tv_nsec = x.tv_nsec - y.tv_nsec;
42 /* Return 1 if result is negative. */
43 return x.tv_sec < y.tv_sec;
49 void Robot::int_handler(int sig) {
53 void Robot::block_signals() {
58 for (i=SIGRTMIN; i<=SIGRTMAX; i++)
59 sigaddset(&sigset, i);
61 pthread_sigmask(SIG_BLOCK, &sigset, (sigset_t*)NULL);
73 * Initializes the robot.
74 * Setup fields in robot structure, initializes FSMs and ORTE.
80 pthread_mutexattr_t mattr;
81 rv = pthread_mutexattr_init(&mattr);
82 #ifdef HAVE_PRIO_INHERIT
83 rv = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
85 pthread_mutex_init(&robot.lock, &mattr);
86 pthread_mutex_init(&robot.lock_ref_pos, &mattr);
87 pthread_mutex_init(&robot.lock_est_pos_odo, &mattr);
88 pthread_mutex_init(&robot.lock_est_pos_indep_odo, &mattr);
89 pthread_mutex_init(&robot.lock_meas_angles, &mattr);
90 pthread_mutex_init(&robot.lock_joy_data, &mattr);
91 pthread_mutex_init(&robot.lock_disp, &mattr);
92 MOTION = sched.create_processor<FSMMotion>();
96 if (team_color == VIOLET) {
97 ul_loginf("We are VIOLET!\n");
99 ul_loginf("We are RED!\n");
102 set_est_pos_trans(ROBOT_START_X_M, ROBOT_START_Y_M, DEG2RAD(ROBOT_START_ANGLE_DEG));
104 ignore_hokuyo = false;
106 // fill_in_known_areas_in_map();
108 signal(SIGINT, int_handler);
109 signal(SIGTERM, int_handler);
113 orte.motion_speed.left = 0;
114 orte.motion_speed.right = 0;
116 orte.pwr_ctrl.voltage33 = 1;
117 orte.pwr_ctrl.voltage50 = 1;
118 orte.pwr_ctrl.voltage80 = 1;
120 orte.camera_control.on = true;
123 /* Only activate display if it is configured */
125 robot.sercom = uoled_init(serial_comm);
126 if (strcmp(robot.sercom->devname, "/dev/null") != 0)
127 robot.fsm.display.state = &fsm_state_disp_init;
130 obstacle_avoidance_enabled = true;
131 use_back_bumpers = true;
132 use_left_bumper = true;
133 use_right_bumper = true;
134 start_state = POWER_ON;
135 check_turn_safety = true;
137 /* init ORTE domain, create publishers, subscribers, .. */
138 rv = robot_init_orte();
144 * Starts the robot FSMs and threads.
151 pthread_attr_t tattr;
152 struct sched_param param;
153 pthread_t thr_obstacle_forgeting;
156 ret = motion_control_init();
158 perror("motion_control_init");
163 /* Obstacle forgeting thread */
164 pthread_attr_init (&tattr);
165 pthread_attr_getschedparam (&tattr, ¶m);
166 pthread_attr_getschedparam (&tattr, ¶m);
167 pthread_attr_setschedpolicy(&tattr, SCHED_FIFO);
168 param.sched_priority = OBST_FORGETING_PRIO;
169 rv = pthread_attr_setschedparam (&tattr, ¶m);
171 perror("robot_start: pthread_attr_setschedparam()");
174 rv = pthread_create(&thr_obstacle_forgeting,
175 &tattr, thread_obstacle_forgeting, NULL);
177 perror("robot_start: pthread_create");
181 sched(); // start main loop
188 * Signals all the robot threads to finish.
190 void Robot::robot_exit() {
196 * Stops the robot. All resources alocated by robot_init() or
197 * robot_start() are dealocated here.
199 void Robot::destroy() {
200 motion_control_done();
202 robottype_roboorte_destroy(&orte);
204 // sched.terminate();
205 // fsm_destroy(&robot.fsm.main);
206 // fsm_destroy(&robot.fsm.motion);
207 // fsm_destroy(&robot.fsm.act);
208 /*robot.map.ShmapFree();*/
209 // ul_logdeb("robofsm: stop.\n");
213 void Robot::get_est_pos_trans(double &x, double &y, double &phi) {
214 get_est_pos(x, y, phi);
217 phi = trans_angle(phi);
220 void Robot::get_est_pos(double &x, double &y, double &phi) {
221 if (indep_odometry_works) {
222 Guard g(lock_est_pos_indep_odo);
223 x = est_pos_indep_odo.x;
224 y = est_pos_indep_odo.y;
225 phi = est_pos_indep_odo.phi;
226 } else if (odometry_works) {
227 Guard g(lock_est_pos_odo);
230 phi = est_pos_odo.phi;
232 Guard g(lock_ref_pos);
239 /** Sets actual position of the robot and with respoect to color of
240 * the team. Should be used for setting initial position of the
242 void Robot::set_est_pos(double x, double y, double phi) {
244 if (x>PLAYGROUND_WIDTH_M) x=PLAYGROUND_WIDTH_M;
246 if (y>PLAYGROUND_HEIGHT_M) y=PLAYGROUND_HEIGHT_M;
249 Guard g(lock_est_pos_indep_odo);
250 est_pos_indep_odo.x = x;
251 est_pos_indep_odo.y = y;
252 est_pos_indep_odo.phi = phi;
256 Guard g(lock_est_pos_odo);
259 est_pos_odo.phi = phi;
263 Guard g(lock_ref_pos);
270 float Robot::current_time() {
271 timespec now, diff, start_local;
272 start_local = startTime;
273 clock_gettime(CLOCK_MONOTONIC, &now);
274 timespec_subtract(diff, now, start_local);
275 return diff.tv_sec + diff.tv_nsec/1000000000.0;