From 6548d83aa655176ef939817e36cd05d0e6cfaccd Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 23 May 2011 01:23:43 +0200 Subject: digital/{io,io-hub,ai}: add generic radar, add radar to robospierre --- digital/ai/src/move/radar.c | 168 +++++++++++++++++++++++++ digital/ai/src/move/radar.h | 96 ++++++++++++++ digital/io-hub/src/robospierre/Makefile | 3 +- digital/io-hub/src/robospierre/bot.h | 3 + digital/io-hub/src/robospierre/main.c | 13 +- digital/io-hub/src/robospierre/radar_defs.c | 46 +++++++ digital/io-hub/src/robospierre/radar_defs.h | 41 ++++++ digital/io-hub/src/robospierre/simu.host.c | 15 +++ digital/io-hub/src/robospierre/simu.host.h | 10 ++ digital/io-hub/tools/io_hub/mex.py | 22 ++++ digital/io/src/Makefile | 4 +- digital/io/src/radar.c | 189 ---------------------------- digital/io/src/radar.h | 78 ------------ digital/io/src/radar_defs.c | 54 ++++++++ digital/io/src/radar_defs.h | 41 ++++++ host/simu/robots/robospierre/model/bag.py | 1 + host/simu/robots/robospierre/view/bag.py | 1 + 17 files changed, 514 insertions(+), 271 deletions(-) create mode 100644 digital/ai/src/move/radar.c create mode 100644 digital/ai/src/move/radar.h create mode 100644 digital/io-hub/src/robospierre/radar_defs.c create mode 100644 digital/io-hub/src/robospierre/radar_defs.h delete mode 100644 digital/io/src/radar.c delete mode 100644 digital/io/src/radar.h create mode 100644 digital/io/src/radar_defs.c create mode 100644 digital/io/src/radar_defs.h diff --git a/digital/ai/src/move/radar.c b/digital/ai/src/move/radar.c new file mode 100644 index 00000000..a572afba --- /dev/null +++ b/digital/ai/src/move/radar.c @@ -0,0 +1,168 @@ +/* radar.c */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "common.h" +#include "radar.h" + +#include "bot.h" + +#include "modules/math/geometry/geometry.h" +#include "modules/math/geometry/distance.h" +#include "modules/utils/utils.h" + +/** Maximum distance for a sensor reading to be ignored if another sensor is + * nearer. */ +#define RADAR_FAR_MM 250 + +/** Define radar configuration. */ +extern struct radar_sensor_t radar_sensors[RADAR_SENSOR_NB]; + +uint8_t +radar_valid (vect_t p); + +/** Compute the center position from several radars sensors, return 1 if + * any. */ +static uint8_t +radar_hit_center (uint8_t valid[], vect_t hit[], uint8_t sensor_nb, + vect_t *obs_pos) +{ + uint8_t i, hit_nb = 0; + vect_t hit_center = { 0, 0 }; + for (i = 0; i < sensor_nb; i++) + { + if (valid[i]) + { + vect_add (&hit_center, &hit[i]); + hit_nb++; + } + } + if (hit_nb > 1) + vect_scale_f824 (&hit_center, 0x1000000l / hit_nb); + if (hit_nb) + { + *obs_pos = hit_center; + return 1; + } + else + return 0; +} + +uint8_t +radar_update (const position_t *robot_pos, vect_t *obs_pos) +{ + uint8_t i, j; + vect_t ray; + uint8_t obs_nb = 0; + /* Compute hit points for each sensor and eliminate invalid ones. */ + vect_t hit[UTILS_COUNT (radar_sensors)]; + uint8_t valid[UTILS_COUNT (radar_sensors)]; + uint16_t dist_mm[UTILS_COUNT (radar_sensors)]; + for (i = 0; i < UTILS_COUNT (radar_sensors); i++) + { + dist_mm[i] = *radar_sensors[i].dist_mm; + if (dist_mm[i] != 0xffff) + { + hit[i] = radar_sensors[i].pos; + vect_rotate_uf016 (&hit[i], robot_pos->a); + vect_translate (&hit[i], &robot_pos->v); + vect_from_polar_uf016 (&ray, dist_mm[i], + robot_pos->a + radar_sensors[i].a); + vect_translate (&hit[i], &ray); + valid[i] = radar_valid (hit[i]); + vect_from_polar_uf016 (&ray, RADAR_OBSTACLE_EDGE_RADIUS_MM, + robot_pos->a + radar_sensors[i].a); + vect_translate (&hit[i], &ray); + } + else + valid[i] = 0; + } + /* Ignore sensor results too far from other sensors. */ + for (i = 0; i < UTILS_COUNT (radar_sensors) - 1; i++) + { + for (j = i + 1; valid[i] && j < UTILS_COUNT (radar_sensors); j++) + { + if (valid[j]) + { + if (dist_mm[i] + RADAR_FAR_MM < dist_mm[j]) + valid[j] = 0; + else if (dist_mm[j] + RADAR_FAR_MM < dist_mm[i]) + valid[i] = 0; + } + } + } + /* Specific treatment about sensor topology. */ + obs_nb += radar_hit_center (valid + RADAR_SENSOR_FRONT_FIRST, + hit + RADAR_SENSOR_FRONT_FIRST, + RADAR_SENSOR_FRONT_NB, &obs_pos[obs_nb]); + obs_nb += radar_hit_center (valid + RADAR_SENSOR_BACK_FIRST, + hit + RADAR_SENSOR_BACK_FIRST, + RADAR_SENSOR_BACK_NB, &obs_pos[obs_nb]); + /* Done. */ + return obs_nb; +} + +uint8_t +radar_blocking (const vect_t *robot_pos, const vect_t *dest_pos, + const vect_t *obs_pos, uint8_t obs_nb) +{ + uint8_t i; + /* Stop here if no obstacle. */ + if (!obs_nb) + return 0; + vect_t vd = *dest_pos; vect_sub (&vd, robot_pos); + uint16_t d = vect_norm (&vd); + /* If destination is realy near, stop here. */ + if (d < RADAR_EPSILON_MM) + return 0; + /* If destination is near, use clearance to destination point instead of + * stop length. */ + vect_t t; + if (d < RADAR_STOP_MM) + t = *dest_pos; + else + { + vect_scale_f824 (&vd, (1ll << 24) / d * RADAR_STOP_MM); + t = *robot_pos; + vect_translate (&t, &vd); + } + /* Now, look at obstacles. */ + for (i = 0; i < obs_nb; i++) + { + /* Vector from robot to obstacle. */ + vect_t vo = obs_pos[i]; vect_sub (&vo, robot_pos); + /* Ignore if in our back. */ + int32_t dp = vect_dot_product (&vd, &vo); + if (dp < 0) + continue; + /* Check distance. */ + int16_t od = distance_segment_point (robot_pos, &t, &obs_pos[i]); + if (od > BOT_SIZE_SIDE + RADAR_CLEARANCE_MM / 2 + + RADAR_OBSTACLE_RADIUS_MM) + continue; + /* Else, obstacle is blocking. */ + return 1; + } + return 0; +} + diff --git a/digital/ai/src/move/radar.h b/digital/ai/src/move/radar.h new file mode 100644 index 00000000..2e37d11d --- /dev/null +++ b/digital/ai/src/move/radar.h @@ -0,0 +1,96 @@ +#ifndef radar_h +#define radar_h +/* radar.h */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "defs.h" + +/** + * Handle any distance sensors information to extract useful data. This + * includes: + * - combining several sensors information for a more precise obstacle + * position, + * - ignoring obstacles not in the playground, + * - determining if an obstacle should make the robot stop. + */ + +/** Estimated obstacle edge radius. As the sensors detect obstacle edge, this is + * added to position obstacle center. */ +#undef RADAR_OBSTACLE_EDGE_RADIUS_MM + +/** Estimated obstacle radius. The obstacle may be larger than at the + * detected edge. */ +#undef RADAR_OBSTACLE_RADIUS_MM + +/** Stop distance. Distance under which an obstacle is considered harmful when + * moving. */ +#undef RADAR_STOP_MM + +/** Clearance distance. Distance over which an obstacle should be to the side + * when moving. + * + * OK, more explanations: when moving, a rectangle is placed in front of the + * robot, of length RADAR_STOP_MM and width 2 * (RADAR_CLEARANCE_MM + + * BOT_SIZE_SIDE). If an obstacle is inside this rectangle, it is considered + * in the way. + * + * If the destination point is near (< RADAR_STOP_MM - RADAR_CLEARANCE_MM), + * this reduce the rectangle length. + * + * If the destination is really near (< RADAR_EPSILON_MM), ignore all this. */ +#undef RADAR_CLEARANCE_MM + +/** Destination distance near enough so that obstacles could be ignored. */ +#undef RADAR_EPSILON_MM + +/* All this in another file. */ +#include "radar_defs.h" + +/** Margin to be considered inside the playground. An obstacle can not be + * exactly at the playground edge. */ +#define RADAR_MARGIN_MM 150 + +/** Describe a radar sensor. */ +struct radar_sensor_t +{ + /** Distance updated by another module. */ + uint16_t *dist_mm; + /** Position relative to the robot center. */ + vect_t pos; + /** Angle relative to the robot X axis. */ + uint16_t a; +}; + +/** Update radar view. Return the number of obstacles found. Obstacles + * positions are returned in obs_pos. */ +uint8_t +radar_update (const position_t *robot_pos, vect_t *obs_pos); + +/** Return non zero if there is a blocking obstacle near the robot while going + * to a destination point. */ +uint8_t +radar_blocking (const vect_t *robot_pos, const vect_t *dest_pos, + const vect_t *obs_pos, uint8_t obs_nb); + +#endif /* radar_h */ diff --git a/digital/io-hub/src/robospierre/Makefile b/digital/io-hub/src/robospierre/Makefile index bd8e920f..fe2b318e 100644 --- a/digital/io-hub/src/robospierre/Makefile +++ b/digital/io-hub/src/robospierre/Makefile @@ -5,6 +5,7 @@ PROGS = io_hub # Sources to compile. io_hub_SOURCES = main.c \ clamp.c logistic.c \ + radar_defs.c radar.c \ init.c fsm.host.c fsm_AI_gen.avr.c fsm_queue.c \ pwm.avr.c pwm.host.c \ contact.avr.c contact.host.c \ @@ -14,7 +15,7 @@ io_hub_SOURCES = main.c \ MODULES = proto uart twi utils \ adc devices/usdist \ math/fixed math/geometry -AI_MODULES = twi_master common utils fsm +AI_MODULES = twi_master common utils fsm move # Configuration file. CONFIGFILE = avrconfig.h AVR_MCU = at90usb1287 diff --git a/digital/io-hub/src/robospierre/bot.h b/digital/io-hub/src/robospierre/bot.h index 5f9d177a..4df9b89d 100644 --- a/digital/io-hub/src/robospierre/bot.h +++ b/digital/io-hub/src/robospierre/bot.h @@ -34,6 +34,9 @@ # define BOT_SCALE 0.0415178942124 #endif +/** Distance from the robot axis to the side. */ +#define BOT_SIZE_SIDE 190 + /** Distance between the front contact point and the robot center. */ #define BOT_FRONT_CONTACT_DIST_MM 150 /** Angle error at the front contact point. */ diff --git a/digital/io-hub/src/robospierre/main.c b/digital/io-hub/src/robospierre/main.c index 8d51c469..6d32c28f 100644 --- a/digital/io-hub/src/robospierre/main.c +++ b/digital/io-hub/src/robospierre/main.c @@ -40,6 +40,7 @@ #include "pwm.h" #include "contact.h" +#include "radar.h" #define FSM_NAME AI #include "fsm.h" @@ -62,6 +63,12 @@ /** Our color. */ enum team_color_e team_color; +/** Obstacles positions, updated using radar module. */ +vect_t main_obstacles_pos[2]; + +/** Number of obstacles in main_obstacles_pos. */ +uint8_t main_obstacles_nb; + /** Asserv stats counters. */ static uint8_t main_stats_asserv_, main_stats_asserv_cpt_; @@ -178,7 +185,11 @@ main_loop (void) contact_update (); if (usdist_update ()) { - /* TODO: update radar. */ + position_t robot_pos; + asserv_get_position (&robot_pos); + main_obstacles_nb = radar_update (&robot_pos, main_obstacles_pos); + //move_obstacles_update (); + simu_send_pos_report (main_obstacles_pos, main_obstacles_nb, 0); } /* Update AI modules. */ logistic_update (); diff --git a/digital/io-hub/src/robospierre/radar_defs.c b/digital/io-hub/src/robospierre/radar_defs.c new file mode 100644 index 00000000..85f015e1 --- /dev/null +++ b/digital/io-hub/src/robospierre/radar_defs.c @@ -0,0 +1,46 @@ +/* radar_defs.c */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "common.h" +#include "radar.h" + +#include "modules/devices/usdist/usdist.h" +#include "playground.h" + +/** Define radar configuration. */ +struct radar_sensor_t radar_sensors[RADAR_SENSOR_NB] = { + { &usdist_mm[0], { 20, 20 }, G_ANGLE_UF016_DEG (10) }, + { &usdist_mm[1], { 20, -20 }, G_ANGLE_UF016_DEG (-10) }, + { &usdist_mm[2], { -20, -20 }, G_ANGLE_UF016_DEG (180 + 10) }, + { &usdist_mm[3], { -20, 20 }, G_ANGLE_UF016_DEG (180 - 10) }, +}; + +/** Define exclusion area (considered as invalid point). */ +uint8_t +radar_valid (vect_t p) +{ + return p.x >= RADAR_MARGIN_MM && p.x < PG_WIDTH - RADAR_MARGIN_MM + && p.y >= RADAR_MARGIN_MM && p.y < PG_LENGTH - RADAR_MARGIN_MM; +} + diff --git a/digital/io-hub/src/robospierre/radar_defs.h b/digital/io-hub/src/robospierre/radar_defs.h new file mode 100644 index 00000000..5f6a2a73 --- /dev/null +++ b/digital/io-hub/src/robospierre/radar_defs.h @@ -0,0 +1,41 @@ +#ifndef radar_defs_h +#define radar_defs_h +/* radar_defs.h */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ + +#define RADAR_OBSTACLE_EDGE_RADIUS_MM 40 +#define RADAR_OBSTACLE_RADIUS_MM 150 +#define RADAR_STOP_MM 350 +#define RADAR_CLEARANCE_MM 100 +#define RADAR_EPSILON_MM 70 + +#define RADAR_SENSOR_NB 4 + +#define RADAR_SENSOR_FRONT_FIRST 0 +#define RADAR_SENSOR_FRONT_NB 2 +#define RADAR_SENSOR_BACK_FIRST 2 +#define RADAR_SENSOR_BACK_NB 2 + +#endif /* radar_defs_h */ diff --git a/digital/io-hub/src/robospierre/simu.host.c b/digital/io-hub/src/robospierre/simu.host.c index f7a43eea..7ca7364b 100644 --- a/digital/io-hub/src/robospierre/simu.host.c +++ b/digital/io-hub/src/robospierre/simu.host.c @@ -34,6 +34,9 @@ /** AVR registers. */ uint8_t PORTA, DDRA, PINA, PINE, PINF; +/** Message types. */ +uint8_t simu_mex_pos_report; + static void simu_adc_handle (void *user, mex_msg_t *msg) { @@ -52,6 +55,7 @@ simu_init (void) mex_instance = host_get_instance ("io-hub0", 0); uint8_t mtype = mex_node_reservef ("%s:adc", mex_instance); mex_node_register (mtype, simu_adc_handle, 0); + simu_mex_pos_report = mex_node_reservef ("%s:pos-report", mex_instance); } /** Make a simulation step. */ @@ -74,3 +78,14 @@ timer_wait (void) return 0; } +void +simu_send_pos_report (vect_t *pos, uint8_t pos_nb, uint8_t id) +{ + mex_msg_t *m; + m = mex_msg_new (simu_mex_pos_report); + mex_msg_push (m, "b", id); + for (; pos_nb; pos++, pos_nb--) + mex_msg_push (m, "hh", pos->x, pos->y); + mex_node_send (m); +} + diff --git a/digital/io-hub/src/robospierre/simu.host.h b/digital/io-hub/src/robospierre/simu.host.h index 6a636851..6224e345 100644 --- a/digital/io-hub/src/robospierre/simu.host.h +++ b/digital/io-hub/src/robospierre/simu.host.h @@ -24,13 +24,23 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * }}} */ +#include "defs.h" #ifdef HOST extern uint8_t PORTA, DDRA, PINA, PINE, PINF; +/** Send general purpose positions to indicate computation results. + * - pos: array of positions to report. + * - pos_nb: number of elements in the array. + * - id: identifier so that several unrelated positions could be reported. */ +void +simu_send_pos_report (vect_t *pos, uint8_t pos_nb, uint8_t id); + #else /* !defined (HOST) */ +#define simu_send_pos_report(pos, pos_nb, id) ((void) 0) + #endif /* !defined (HOST) */ #endif /* simu_host_h */ diff --git a/digital/io-hub/tools/io_hub/mex.py b/digital/io-hub/tools/io_hub/mex.py index 22e9e900..44c41010 100644 --- a/digital/io-hub/tools/io_hub/mex.py +++ b/digital/io-hub/tools/io_hub/mex.py @@ -121,6 +121,27 @@ class Mex: m.push ('L', self.contacts) self.node.send (m) + class PosReport (Observable): + """General purpose position report. + + - pos: dict of sequence of (x, y) coordinates (millimeters). The dict + is indexed by position identifier. + + """ + + def __init__ (self, node, instance): + Observable.__init__ (self) + self.pos = { } + node.register (instance + ':pos-report', self.__handle) + + def __handle (self, msg): + p = [ ] + id, = msg.pop ('b') + while len (msg) >= 4: + p.append (msg.pop ('hh')) + self.pos[id] = p + self.notify () + def __init__ (self, node, instance = 'io-hub0'): self.adc = tuple (self.ADC (node, instance, i) for i in range (0, ADC_NB)) self.pwm = tuple (self.PWM () for i in range (0, PWM_NB)) @@ -128,4 +149,5 @@ class Mex: self.__contact_pack = self.Contact.Pack (node, instance) self.contact = tuple (self.Contact (self.__contact_pack, i) for i in range (CONTACT_NB)) + self.pos_report = self.PosReport (node, instance) diff --git a/digital/io/src/Makefile b/digital/io/src/Makefile index effe9c45..463e148e 100644 --- a/digital/io/src/Makefile +++ b/digital/io/src/Makefile @@ -6,14 +6,14 @@ PROGS = io io_SOURCES = main.c fsm_queue.c servo.avr.c eeprom.avr.c pwm.c \ switch.avr.c chrono.c timer.avr.c servo_pos.c \ twi_master.c asserv.c mimot.c \ - simu.host.c contact.c radar.c \ + simu.host.c contact.c radar.c radar_defs.c \ path.c food.c events.host.c \ fsm.host.c init.c move.c top.c hola.c loader.c fsm_AI_gen.avr.c # Modules needed for IO. MODULES = proto uart twi utils adc math/fixed math/geometry path/astar \ devices/usdist \ trace flash spi -AI_MODULES = twi_master common utils fsm +AI_MODULES = twi_master common utils fsm move # Configuration file. CONFIGFILE = avrconfig.h # IO board use an ATMega128. diff --git a/digital/io/src/radar.c b/digital/io/src/radar.c deleted file mode 100644 index 0f61a1bf..00000000 --- a/digital/io/src/radar.c +++ /dev/null @@ -1,189 +0,0 @@ -/* radar.c */ -/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ - * - * Copyright (C) 2010 Nicolas Schodet - * - * APBTeam: - * Web: http://apbteam.org/ - * Email: team AT apbteam DOT org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * }}} */ -#include "common.h" -#include "radar.h" - -#include "playground_2010.h" -#include "bot.h" - -#include "modules/devices/usdist/usdist.h" -#include "modules/math/geometry/geometry.h" -#include "modules/math/geometry/distance.h" -#include "modules/utils/utils.h" - -/** Margin to be considered inside the playground. An obstacle can not be - * exactly at the playground edge. */ -#define RADAR_MARGIN_MM 150 - -/** Maximum distance for a sensor reading to be ignored if another sensor is - * nearer. */ -#define RADAR_FAR_MM 250 - -/** Describe a radar sensor. */ -struct radar_sensor_t -{ - /** Distance updated by another module. */ - uint16_t *dist_mm; - /** Position relative to the robot center. */ - vect_t pos; - /** Angle relative to the robot X axis. */ - uint16_t a; -}; - -/** Define radar configuration. */ -struct radar_sensor_t radar_sensors[] = { -#define RADAR_SENSOR_FRONT 0 - { &usdist_mm[0], { 30 - 20, 0 }, G_ANGLE_UF016_DEG (0) }, -#define RADAR_SENSOR_LEFT 1 - { &usdist_mm[1], { 20 - 20, 20 }, G_ANGLE_UF016_DEG (30) }, -#define RADAR_SENSOR_RIGHT 2 - { &usdist_mm[2], { 20 - 20, -20 }, G_ANGLE_UF016_DEG (-30) }, -#define RADAR_SENSOR_BACK 3 - { &usdist_mm[3], { -30 - 20, 0 }, G_ANGLE_UF016_DEG (180) }, -}; - -/** Define exclusion area (considered as invalid point). */ -static uint8_t -radar_valid (vect_t p) -{ - return p.x >= RADAR_MARGIN_MM && p.x < PG_WIDTH - RADAR_MARGIN_MM - && p.y >= RADAR_MARGIN_MM && p.y < PG_LENGTH - RADAR_MARGIN_MM - /* Ignore points on slope, no margin for the slope start. */ - && (p.x < PG_WIDTH / 2 - PG_SLOPE_WIDTH / 2 - || p.x >= PG_WIDTH / 2 + PG_SLOPE_WIDTH / 2 - || p.y < PG_LENGTH - PG_SLOPE_LENGTH - RADAR_MARGIN_MM / 2); -} - -uint8_t -radar_update (const position_t *robot_pos, vect_t *obs_pos) -{ - uint8_t i, j; - vect_t ray; - uint8_t obs_nb = 0; - uint8_t front_nb; - vect_t front_center; - /* Compute hit points for each sensor and eliminate invalid ones. */ - vect_t hit[UTILS_COUNT (radar_sensors)]; - uint8_t valid[UTILS_COUNT (radar_sensors)]; - uint16_t dist_mm[UTILS_COUNT (radar_sensors)]; - for (i = 0; i < UTILS_COUNT (radar_sensors); i++) - { - dist_mm[i] = *radar_sensors[i].dist_mm; - if (dist_mm[i] != 0xffff) - { - hit[i] = radar_sensors[i].pos; - vect_rotate_uf016 (&hit[i], robot_pos->a); - vect_translate (&hit[i], &robot_pos->v); - vect_from_polar_uf016 (&ray, dist_mm[i], - robot_pos->a + radar_sensors[i].a); - vect_translate (&hit[i], &ray); - valid[i] = radar_valid (hit[i]); - vect_from_polar_uf016 (&ray, RADAR_OBSTACLE_EDGE_RADIUS_MM, - robot_pos->a + radar_sensors[i].a); - vect_translate (&hit[i], &ray); - } - else - valid[i] = 0; - } - /* Ignore sensor results too far from other sensors. */ - for (i = 0; i < UTILS_COUNT (radar_sensors) - 1; i++) - { - for (j = i + 1; valid[i] && j < UTILS_COUNT (radar_sensors); j++) - { - if (valid[j]) - { - if (dist_mm[i] + RADAR_FAR_MM < dist_mm[j]) - valid[j] = 0; - else if (dist_mm[j] + RADAR_FAR_MM < dist_mm[i]) - valid[i] = 0; - } - } - } - /* Specific treatment about sensor topology. */ - if (valid[RADAR_SENSOR_BACK]) - obs_pos[obs_nb++] = hit[RADAR_SENSOR_BACK]; - front_nb = 0; - front_center.x = 0; front_center.y = 0; - for (i = RADAR_SENSOR_FRONT; i < RADAR_SENSOR_BACK; i++) - { - if (valid[i]) - { - vect_add (&front_center, &hit[i]); - front_nb++; - } - } - if (front_nb) - { - vect_scale_f824 (&front_center, 0x1000000l / front_nb); - obs_pos[obs_nb++] = front_center; - } - /* Done. */ - return obs_nb; -} - -uint8_t -radar_blocking (const vect_t *robot_pos, const vect_t *dest_pos, - const vect_t *obs_pos, uint8_t obs_nb) -{ - uint8_t i; - /* Stop here if no obstacle. */ - if (!obs_nb) - return 0; - vect_t vd = *dest_pos; vect_sub (&vd, robot_pos); - uint16_t d = vect_norm (&vd); - /* If destination is realy near, stop here. */ - if (d < RADAR_EPSILON_MM) - return 0; - /* If destination is near, use clearance to destination point instead of - * stop length. */ - vect_t t; - if (d < RADAR_STOP_MM) - t = *dest_pos; - else - { - vect_scale_f824 (&vd, (1ll << 24) / d * RADAR_STOP_MM); - t = *robot_pos; - vect_translate (&t, &vd); - } - /* Now, look at obstacles. */ - for (i = 0; i < obs_nb; i++) - { - /* Vector from robot to obstacle. */ - vect_t vo = obs_pos[i]; vect_sub (&vo, robot_pos); - /* Ignore if in our back. */ - int32_t dp = vect_dot_product (&vd, &vo); - if (dp < 0) - continue; - /* Check distance. */ - int16_t od = distance_segment_point (robot_pos, &t, &obs_pos[i]); - if (od > BOT_SIZE_SIDE + RADAR_CLEARANCE_MM / 2 - + RADAR_OBSTACLE_RADIUS_MM) - continue; - /* Else, obstacle is blocking. */ - return 1; - } - return 0; -} - diff --git a/digital/io/src/radar.h b/digital/io/src/radar.h deleted file mode 100644 index b4611ec7..00000000 --- a/digital/io/src/radar.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef radar_h -#define radar_h -/* radar.h */ -/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ - * - * Copyright (C) 2010 Nicolas Schodet - * - * APBTeam: - * Web: http://apbteam.org/ - * Email: team AT apbteam DOT org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * }}} */ -#include "defs.h" - -/** - * Handle any distance sensors information to extract useful data. This - * includes: - * - combining several sensors information for a more precise obstacle - * position, - * - ignoring obstacles not in the playground, - * - determining if an obstacle should make the robot stop. - */ - -/** Estimated obstacle edge radius. As the sensors detect obstacle edge, this is - * added to position obstacle center. */ -#define RADAR_OBSTACLE_EDGE_RADIUS_MM 40 - -/** Estimated obstacle radius. The obstacle may be larger than at the - * detected edge. */ -#define RADAR_OBSTACLE_RADIUS_MM 150 - -/** Stop distance. Distance under which an obstacle is considered harmful when - * moving. */ -#define RADAR_STOP_MM 350 - -/** Clearance distance. Distance over which an obstacle should be to the side - * when moving. - * - * OK, more explanations: when moving, a rectangle is placed in front of the - * robot, of length RADAR_STOP_MM and width 2 * (RADAR_CLEARANCE_MM + - * BOT_SIZE_SIDE). If an obstacle is inside this rectangle, it is considered - * in the way. - * - * If the destination point is near (< RADAR_STOP_MM - RADAR_CLEARANCE_MM), - * this reduce the rectangle length. - * - * If the destination is really near (< RADAR_EPSILON_MM), ignore all this. */ -#define RADAR_CLEARANCE_MM 100 - -/** Destination distance near enough so that obstacles could be ignored. */ -#define RADAR_EPSILON_MM 70 - -/** Update radar view. Return the number of obstacles found. Obstacles - * positions are returned in obs_pos. */ -uint8_t -radar_update (const position_t *robot_pos, vect_t *obs_pos); - -/** Return non zero if there is a blocking obstacle near the robot while going - * to a destination point. */ -uint8_t -radar_blocking (const vect_t *robot_pos, const vect_t *dest_pos, - const vect_t *obs_pos, uint8_t obs_nb); - -#endif /* radar_h */ diff --git a/digital/io/src/radar_defs.c b/digital/io/src/radar_defs.c new file mode 100644 index 00000000..2787ed97 --- /dev/null +++ b/digital/io/src/radar_defs.c @@ -0,0 +1,54 @@ +/* radar_defs.c */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ +#include "common.h" +#include "radar.h" + +#include "modules/devices/usdist/usdist.h" +#include "playground_2010.h" + +/** Define radar configuration. */ +struct radar_sensor_t radar_sensors[RADAR_SENSOR_NB] = { +#define RADAR_SENSOR_FRONT 0 + { &usdist_mm[0], { 30 - 20, 0 }, G_ANGLE_UF016_DEG (0) }, +#define RADAR_SENSOR_LEFT 1 + { &usdist_mm[1], { 20 - 20, 20 }, G_ANGLE_UF016_DEG (30) }, +#define RADAR_SENSOR_RIGHT 2 + { &usdist_mm[2], { 20 - 20, -20 }, G_ANGLE_UF016_DEG (-30) }, +#define RADAR_SENSOR_BACK 3 + { &usdist_mm[3], { -30 - 20, 0 }, G_ANGLE_UF016_DEG (180) }, +}; + +/** Define exclusion area (considered as invalid point). */ +uint8_t +radar_valid (vect_t p) +{ + return p.x >= RADAR_MARGIN_MM && p.x < PG_WIDTH - RADAR_MARGIN_MM + && p.y >= RADAR_MARGIN_MM && p.y < PG_LENGTH - RADAR_MARGIN_MM + /* Ignore points on slope, no margin for the slope start. */ + && (p.x < PG_WIDTH / 2 - PG_SLOPE_WIDTH / 2 + || p.x >= PG_WIDTH / 2 + PG_SLOPE_WIDTH / 2 + || p.y < PG_LENGTH - PG_SLOPE_LENGTH - RADAR_MARGIN_MM / 2); +} + diff --git a/digital/io/src/radar_defs.h b/digital/io/src/radar_defs.h new file mode 100644 index 00000000..51bc5943 --- /dev/null +++ b/digital/io/src/radar_defs.h @@ -0,0 +1,41 @@ +#ifndef radar_defs_h +#define radar_defs_h +/* radar_defs.h */ +/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{ + * + * Copyright (C) 2010 Nicolas Schodet + * + * APBTeam: + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * }}} */ + +#define RADAR_OBSTACLE_EDGE_RADIUS_MM 40 +#define RADAR_OBSTACLE_RADIUS_MM 150 +#define RADAR_STOP_MM 350 +#define RADAR_CLEARANCE_MM 100 +#define RADAR_EPSILON_MM 70 + +#define RADAR_SENSOR_NB 4 + +#define RADAR_SENSOR_FRONT_FIRST 0 +#define RADAR_SENSOR_FRONT_NB 3 +#define RADAR_SENSOR_BACK_FIRST 3 +#define RADAR_SENSOR_BACK_NB 1 + +#endif /* radar_defs_h */ diff --git a/host/simu/robots/robospierre/model/bag.py b/host/simu/robots/robospierre/model/bag.py index de8eaa22..260960f8 100644 --- a/host/simu/robots/robospierre/model/bag.py +++ b/host/simu/robots/robospierre/model/bag.py @@ -54,4 +54,5 @@ class Bag: DistanceSensorSensopart (link_bag.io_hub.adc[3], scheduler, table, (-20, 20), pi - pi * 10 / 180, (self.position, ), 2), ] + self.pos_report = link_bag.io_hub.pos_report diff --git a/host/simu/robots/robospierre/view/bag.py b/host/simu/robots/robospierre/view/bag.py index 0b5a85ad..73aa9fe3 100644 --- a/host/simu/robots/robospierre/view/bag.py +++ b/host/simu/robots/robospierre/view/bag.py @@ -43,4 +43,5 @@ class Bag: ClampSide.height), model_bag.clamp)) self.distance_sensor = [DistanceSensorUS (self.robot, ds) for ds in model_bag.distance_sensor] + self.pos_report = PosReport (table, model_bag.pos_report) -- cgit v1.2.3