3 * @brief Useful functions related map
4 * @author Jose Maria Martin Laguna <jmmartin@etud.insa-toulouse.fr>
6 * This file contains functions to manage map.
7 * The map should be accessed only by this library.
9 * @todo Lock the map! It necessary in multi-thread programs. If while
10 * we are doing something in the map, somewhere the function
11 * ShmapFree() is called, segfault occurs.
21 struct map* map = NULL;
23 /** @addtogroup maplib */
31 * @name Shared Memory Map related functions
35 * @brief Init Shared Map memory
37 * @param init_flag 1 to init the map memory and set all cells with
38 * #MAP_FREE and #MAP_FLAG_NO_FLAG, 0 only init map
39 * @return Pointer to the map. In case of error, exit() is called.
41 * This function allocates memory for shared map if this memory does
44 struct map *ShmapInit(int init_flag){
45 const int shmap_size = sizeof(struct map);
47 // Allocate memory to shared map
48 shmap_id = shmget (SHM_MAP_KEY , shmap_size, IPC_CREAT | S_IRUSR | S_IWUSR); // Removed flag IPC_EXCL
55 /* Attach the shared memory segment. */
56 map = (struct map *) shmat (shmap_id, 0, 0);
63 /* Initialize Map Memory */
64 if (init_flag) ShmapAllFreeSpace();
66 //printf("Map initialized\n");
73 * @brief Free Shared Map memory
76 /* Deatch the shared memory segment. */
79 /* Deallocate the shared memory segment. */
80 shmctl (shmap_id, IPC_RMID, 0);
84 * @brief Deatach Shared Map memory
87 /* Deatch the shared memory segment. */
92 * @brief Check if Shared Map memory is init
93 * @return Pointer to the map or NULL if not initialized.
95 struct map * ShmapIsMapInit(void)
107 * @brief Initialize Map Memory with #MAP_FREE value and #MAP_FLAG_NO_FLAG flag.
110 void ShmapAllFreeSpace(void){
112 for (j=0;j<MAP_HEIGHT;j++){
113 for(i=0;i<MAP_WIDTH;i++){
114 map->cells[j][i].flags = 0;
115 map->cells[j][i].detected_obstacle = 0;
120 struct map_cell ShmapNoCell;
123 * @brief Put a value in a point
124 * @param x_m Coordonate X (in m) of a point
125 * @param y_m Coordonate Y (in m) of a point
126 * @param value Value of the point
127 * @return Pointer to the cell. If coordinates are outside of the map,
128 * pointer to ::ShmapNoCell is returned.
130 struct map_cell *ShmapCellAtPoint(double x_m, double y_m)
134 ShmapPoint2Cell(x_m, y_m, &i, &j, &valid);
136 return &(map->cells[j][i]);
142 * @brief Give information about if a cell is free.
143 * @param x Coordonate of a cell
144 * @param y Coordonate of a cell
145 * @return 1 if the cell is not an obstacle, -1 if the cell is not in
146 * the map, 0 otherwise
148 * Following cells are consider as free cells: #MAP_START, #MAP_GOAL,
149 * #MAP_PATH, #MAP_FREE.
151 int ShmapIsFreeCell(int x, int y)
153 struct map_cell *cell;
154 if(map && ShmapIsCellInMap(x,y)) {
156 cell = &(map->cells[y][x]);
157 free = (cell->detected_obstacle == 0) &&
158 (((cell->flags & (MAP_FLAG_WALL|MAP_FLAG_DET_OBST|MAP_FLAG_PLAN_MARGIN)) == 0) ||
159 ((cell->flags & MAP_FLAG_WALL) && (cell->flags & MAP_FLAG_INVALIDATE_WALL)));
165 int ShmapIsFreePoint(double x_m, double y_m)
169 ShmapPoint2Cell(x_m, y_m, &i, &j, &valid);
170 return ShmapIsFreeCell(i, j);
176 * @brief Creates an obstacle in the map with a square shape
177 * @param xs Coordonate X (in m) of the central point
178 * @param ys Coordonate Y (in m) of the central point
179 * @param r Radius (in m)
180 * @param cell Type of obstacle.
183 int ShmapSetCircleFlag(double xs, double ys, double r, map_cell_flag_t set_flags, map_cell_flag_t clear_flags)
185 int i,j, i1, i2, j1, j2;
187 // define a circumscribe square - just to shorten cyclic pass through the playground
188 //ShmapPoint2Cell(xs-r, ys-r, &i1, &j1, &valid);
189 //ShmapPoint2Cell(xs+r, ys+r, &i2, &j2, &valid);
197 for(i=i1; i<=i2; i++) {
198 for(j=j1; j<=j2; j++) {
199 //DBG("Wall in (%d,%d)\n", i,j);
200 if (!ShmapIsCellInMap(i, j)) continue;
201 ShmapCell2Point(i, j, &xp, &yp); // get the central point of the cell
202 // determine if the CENTRAL point of the cell is inside the circle
203 if (! ( pow(xp-xs, 2)+pow(yp-ys, 2) < pow(r, 2) /*v kruhu*/)) continue;
204 map->cells[j][i].flags &= ~clear_flags;
205 map->cells[j][i].flags |= set_flags;
212 * @brief Creates an obstacle in the map
213 * @param x1 Coordonate X (in m) of the first point
214 * @param y1 Coordonate Y (in m) of the first point
215 * @param x2 Coordonate X (in m) of the second point
216 * @param y2 Coordonate Y (in m) of the second point
217 * @param cell Type of obstacle.
220 int ShmapSetRectangleFlag(double x1, double y1, double x2, double y2, map_cell_flag_t set_flags, map_cell_flag_t clear_flags)
222 int i,j, i1, i2, j1, j2;
224 ShmapPoint2Cell(x1, y1, &i1, &j1, &valid);
225 ShmapPoint2Cell(x2, y2, &i2, &j2, &valid);
238 //DBG("Drawing a rectangle between points (%d, %d) and (%d,%d)\n", init_i,init_j,limit_i,limit_j);
239 for(i=i1; i<=i2; i++) {
240 for(j=j1; j<=j2; j++) {
241 //DBG("Wall in (%d,%d)\n", i,j);
242 if (!ShmapIsCellInMap(i, j)) continue;
243 map->cells[j][i].flags &= ~clear_flags;
244 map->cells[j][i].flags |= set_flags;
254 * @name Coordonates translation
258 * @brief Translates from real X coordonate (in meters) to grid cell coordonates
259 * @param x Coodonte of X
262 void ShmapPoint2Cell(double x, double y, int *ix, int *iy, bool *valid){
264 xx = (int)floor(x/MAP_CELL_SIZE_M);
265 yy = MAP_HEIGHT-1-(int)floor(y/MAP_CELL_SIZE_M);
268 *valid = ( ( xx < MAP_WIDTH ) && (yy < MAP_HEIGHT) && ( xx >= 0 ) && ( yy >= 0) );
275 * @brief Translates from cell X coordonate to real coordonate.
276 * @param x Coodonte X of a cell.
277 * @return X value in real coordonate, -1 if the coordonate is not in map
279 int ShmapCell2Point(int ix, int iy, double *x, double *y)
281 if ( (ix >= 0) && (ix <= MAP_WIDTH-1)) {
282 if (x) *x = (ix+0.5)*MAP_CELL_SIZE_M;
286 if ( (iy>=0) && (iy<=(MAP_HEIGHT-1))) {
287 if (y) *y =((MAP_HEIGHT-1-iy)+0.5)*MAP_CELL_SIZE_M;