Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / scout / libscout / src / behaviors / navigationMap.cpp @ ca164875

History | View | Annotate | Download (9.32 KB)

1 2d697b1f Leon
/**
2
 * Copyright (c) 2011 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
26
/**
27
 * @file navigationMap.cpp
28
 * @brief Contains navigation map Behavior declarations and definitions
29
 * 
30
 * Contains functions and definitions for the use of
31
 * navigation map Behavior 
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 * @author Priya Deo
35
 * @author Lalitha
36
 * @author James
37
 * @author Leon
38
 **/
39
40 d8caf546 Priya
#include "navigationMap.h"
41
42 cccc25c9 Priya
using namespace std;
43
44 2d697b1f Leon
/**
45
 * @brief Initializes the navigation map
46
 *
47
 * Initialize the navigation map. 
48
 * The map itself is represented as a dynamic array of edge arrays
49
 * @param the string name of the scout
50
 */
51 cccc25c9 Priya
navigationMap::navigationMap(string scoutname) : Behavior(scoutname, "navigationMap")
52 d8caf546 Priya
{
53
  /** Initialize Map 
54
   *
55
   *   1           2          3         4
56
   *  ----|-----------|----------|---------|---------->
57
   *  <---|--5--------|--6-------|--7------|--8-------
58
   *      |           |          |         |
59
   *     9|         10|        11|       12|
60
   *      |           |          |         |
61
   *     ---         ---        ---       ---
62
   */
63
  
64 738e44fb Priya
    Edge* a1 = new Edge[ARRAY_SIZE];
65
    a1[0] = MAKE_EDGE(ISTRAIGHT, 2, 10);
66
    a1[1] = MAKE_EDGE(IRIGHT, 9, 40);
67
    a1[2] = MAKE_EDGE(IUTURN, DEADEND, 0);
68
69
    Edge* a2 = new Edge[ARRAY_SIZE]; 
70
    a2[0] = MAKE_EDGE(ISTRAIGHT, 3, 10);
71
    a2[1] = MAKE_EDGE(IRIGHT, 10, 40);
72
    a2[2] = MAKE_EDGE(IUTURN, 5, 10);
73
74
    Edge* a3 = new Edge[ARRAY_SIZE]; 
75
    a3[0] = MAKE_EDGE(ISTRAIGHT, 4, 10);
76
    a3[1] = MAKE_EDGE(IRIGHT, 11, 40);
77
    a3[2] = MAKE_EDGE(IUTURN, 6, 10);
78
79
    Edge* a4 = new Edge[ARRAY_SIZE]; 
80
    a4[0] = MAKE_EDGE(ISTRAIGHT, DEADEND, 0);
81
    a4[1] = MAKE_EDGE(IRIGHT, 12, 40);
82
    a4[2] = MAKE_EDGE(IUTURN, 7, 10);
83
84
    Edge* a5 = new Edge[ARRAY_SIZE];
85
    a5[0] = MAKE_EDGE(ISTRAIGHT, DEADEND, 0);
86
    a5[1] = MAKE_EDGE(ILEFT, 9, 40);
87
    a5[2] = MAKE_EDGE(IUTURN, 2, 10);
88
89
    Edge* a6 = new Edge[ARRAY_SIZE];
90
    a6[0] = MAKE_EDGE(ISTRAIGHT, 5, 0);
91
    a6[1] = MAKE_EDGE(ILEFT, 10, 40);
92
    a6[2] = MAKE_EDGE(IUTURN, 3, 10);
93
94
    Edge* a7 = new Edge[ARRAY_SIZE];
95
    a7[0] = MAKE_EDGE(ISTRAIGHT, 6, 0);
96
    a7[1] = MAKE_EDGE(ILEFT, 11, 40);
97
    a7[2] = MAKE_EDGE(IUTURN, 3, 10);
98
99
    Edge* a8 = new Edge[ARRAY_SIZE];
100
    a8[0] = MAKE_EDGE(ISTRAIGHT, 7, 0);
101
    a8[1] = MAKE_EDGE(ILEFT, 12, 40);
102
    a8[2] = MAKE_EDGE(IUTURN, DEADEND, 10);
103
104
    Edge* a9 = new Edge[ARRAY_SIZE];
105
    a9[0] = MAKE_EDGE(IRIGHT, 2, 10);
106
    a9[1] = MAKE_EDGE(ILEFT, DEADEND, 0);
107
    a9[2] = MAKE_EDGE(IUTURN, 9, 40);
108
109
    Edge* a10 = new Edge[ARRAY_SIZE];
110
    a10[0] = MAKE_EDGE(IRIGHT, 3, 10);
111
    a10[1] = MAKE_EDGE(ILEFT, 5, 10);
112
    a10[2] = MAKE_EDGE(IUTURN, 10, 40);
113
114
    Edge* a11 = new Edge[ARRAY_SIZE];
115
    a11[0] = MAKE_EDGE(IRIGHT, 4, 10);
116
    a11[1] = MAKE_EDGE(ILEFT, 6, 10);
117
    a11[2] = MAKE_EDGE(IUTURN, 11, 40);
118
119
    Edge* a12 = new Edge[ARRAY_SIZE];
120
    a12[0] = MAKE_EDGE(IRIGHT, DEADEND, 0);
121
    a12[1] = MAKE_EDGE(ILEFT, 7, 10);
122
    a12[2] = MAKE_EDGE(IUTURN, 12, 40);
123
124
    map.push_back(a1);
125
    map.push_back(a2);
126
    map.push_back(a3);
127
    map.push_back(a4);
128
    map.push_back(a5);
129
    map.push_back(a6);
130
    map.push_back(a7);
131
    map.push_back(a8);
132
    map.push_back(a9);
133
    map.push_back(a10);
134
    map.push_back(a11);
135
    map.push_back(a12);
136
137
    curr_state = START_STATE;
138 cccc25c9 Priya
    arrival_time = ros::TIME_MAX;
139 d8caf546 Priya
}
140
141
/** @brief Goes through and frees all allocated memory */
142
navigationMap::~navigationMap()
143
{
144 738e44fb Priya
  while(!map.empty())
145
  {
146
    Edge* temp = map.back();
147
    map.pop_back();
148
    delete temp;
149
  }
150
  return;
151 d8caf546 Priya
}
152
153 2d697b1f Leon
/** @brief FSM implementation*/
154 cccc25c9 Priya
void navigationMap::run()
155 d8caf546 Priya
{
156 cccc25c9 Priya
  Duration t;
157
  ROS_INFO("My state is: %d\n", curr_state);
158
  //Straight, straight, right, left, straight 5
159
  update_state(ISTRAIGHT);
160
  ROS_INFO("My state is: %d\n", curr_state);
161
  t = get_time_remaining();
162
  while(t.toSec() > 0)
163
    t = get_time_remaining();
164
  update_state(ISTRAIGHT);
165
  ROS_INFO("My state is: %d\n", curr_state);
166
  t = get_time_remaining();
167
  while(t.toSec() > 0)
168
    t = get_time_remaining();
169
  update_state(IRIGHT);
170
  ROS_INFO("My state is: %d\n", curr_state);
171
  t = get_time_remaining();
172
  while(t.toSec() > 0)
173
    t = get_time_remaining();
174
  update_state(ILEFT);
175
  ROS_INFO("My state is: %d\n", curr_state);
176
  t = get_time_remaining();
177
  while(t.toSec() > 0)
178
    t = get_time_remaining();
179
  update_state(ISTRAIGHT);
180
  ROS_INFO("My state is: %d\n", curr_state);
181
  t = get_time_remaining();
182
  while(t.toSec() > 0)
183
    t = get_time_remaining();
184
  ROS_INFO("Traveled route!\n");
185 6642eee3 Priya
186
  ROS_INFO("Going to state 6\n");
187
  Path path = shortest_path(6);
188
  if(path.path == NULL)
189
    return;
190
191
  ROS_INFO("Now at state %d\n", curr_state);
192
  for(int i=0; i<path.len; i++)
193
  {
194
    update_state(path.path[i]);
195
    ROS_INFO("Made turn %d, at state %d\n", path.path[i], curr_state);
196
    t = get_time_remaining();
197
    while(t.toSec() > 0)
198
      t = get_time_remaining();
199
    ROS_INFO("Now at state %d\n", curr_state);
200
  }
201
  ROS_INFO("Traveled route!\n");
202
203 cccc25c9 Priya
  while(ok())
204
    continue;
205 d8caf546 Priya
}
206
207 2d697b1f Leon
/**@brief sets the current state to the state associated with the turn made
208
 * @param the Turn that we made from our state
209
 * @return our new State after making the turn 
210
 */
211 cccc25c9 Priya
State navigationMap::update_state(Turn turn_made)
212 ede03b64 James Carroll
{
213 57e82e6c James Carroll
  Edge* possible_edges = get_outbound_edges(curr_state);
214 6642eee3 Priya
  for(int i=0;i<ARRAY_SIZE;i++)
215 738e44fb Priya
  {
216
    //sets the current state to the state associated with the turn made
217
    if(GET_EDGE_DIR(possible_edges[i]) == turn_made)
218
    {
219
      int speed = 10000;//its over 9000
220 57e82e6c James Carroll
      curr_state = GET_EDGE_STATE(possible_edges[i]);
221 738e44fb Priya
      //TODO: get actual speed
222 cccc25c9 Priya
      Duration travel_time(GET_EDGE_DIST(possible_edges[i])/speed);
223
      arrival_time = Time::now() + travel_time;
224 57e82e6c James Carroll
      return curr_state;
225 738e44fb Priya
    }
226
  }
227
  return -1;//failure to succeed
228 ede03b64 James Carroll
}
229
230 2d697b1f Leon
/**@brief returns the predicted time of arrival for our current task
231
 * @return the predicted time of arrival for our current task
232
 */
233 cccc25c9 Priya
Time navigationMap::get_eta()
234 ede03b64 James Carroll
{
235 738e44fb Priya
  return arrival_time;
236 ede03b64 James Carroll
}
237
238 2d697b1f Leon
/**@brief returns the predicted amount of time it will take to finish our task
239
 * @return the predicted amount of time it will take to finish our task
240
 */
241 cccc25c9 Priya
Duration navigationMap::get_time_remaining()
242 ede03b64 James Carroll
{
243 cccc25c9 Priya
  return (arrival_time - Time::now());
244 ede03b64 James Carroll
}
245
246 2d697b1f Leon
/**@brief returns the current state of the scout in the map
247
 * @return the current State (ie: int) of the scout in the map
248
 */
249 cccc25c9 Priya
State navigationMap::get_state()
250 d8caf546 Priya
{
251 738e44fb Priya
  return curr_state;
252 d8caf546 Priya
}
253
254 2d697b1f Leon
/**@brief returns the Edges connecting from a given State
255
 * @param the State whose edges we want to get
256
 * @return the Edges connecting from the given State
257
 */
258 cccc25c9 Priya
Edge* navigationMap::get_outbound_edges(State state)
259 0b6591e2 Priya
{
260 cccc25c9 Priya
  return map.at(state-1); 
261 0b6591e2 Priya
}
262
263 2d697b1f Leon
/**@brief uses BFS to find the shortest path to a target State node
264
 * @param the State that we want to get to
265
 * @return a Path struct containing the Turn* to take to get to the target state
266
 */
267 738e44fb Priya
Path navigationMap::shortest_path(State target_state)
268 d8caf546 Priya
{
269 738e44fb Priya
  // BFS algorithm
270
  State curr_state = get_state();
271
  int visited[MAX_NODES+1] = {0};
272
273
  queue<State> q;
274
  q.push(curr_state);
275
  // not zero = visited, zero = unvisited, negative = start state
276
  visited[curr_state] = -1;
277
278
  while (!q.empty())
279
  {
280
    State state = q.front();
281
    //actually dequeue it
282
    q.pop();
283
    if (state == target_state)
284 6642eee3 Priya
    {  
285 738e44fb Priya
      Path path;
286 6642eee3 Priya
      path.path = (Turn*)calloc(sizeof(Turn), MAX_NODES);
287 738e44fb Priya
      int j = 0; // counter
288
      for(State child = state; visited[child] >= 0; 
289
          child = visited[child]) //while not start state
290
      {
291
        State parent = visited[child];
292
        Edge* edges = get_outbound_edges(parent);
293
        for (int i = 0; i < ARRAY_SIZE; i++)
294 93210a92 Leon
        {
295 738e44fb Priya
          if (GET_EDGE_STATE(edges[i]) == child)
296
          {
297
            path.path[j] = GET_EDGE_DIR(edges[i]);
298
            j++;
299
            break;
300
          }
301 93210a92 Leon
        }
302 738e44fb Priya
      }
303
      /** Reverse moves list */
304
      for (int i = 0; i < j/2; i++)
305
      {
306
        path.path[i] ^= path.path[j-i-1];
307
        path.path[j-i-1] ^= path.path[i];
308
        path.path[i] ^= path.path[j-i-1];
309
      }
310
      path.len = j;
311
      return path;
312
    }
313
    Edge* edges = get_outbound_edges(state);
314 6642eee3 Priya
315 738e44fb Priya
    for (int i = 0; i < ARRAY_SIZE; i++)
316
    {
317
      State new_state = GET_EDGE_STATE(edges[i]);
318
      if (new_state != DEADEND && !visited[new_state]) 
319
      {
320 2d697b1f Leon
        // set this state in visited as the parent of the new_state
321 738e44fb Priya
        visited[new_state] = state;
322
        q.push(new_state);
323
      }
324 93210a92 Leon
    }
325 738e44fb Priya
  }
326
  //oops, no way to get to target from state
327
  Path path;
328
  path.len = 0;
329
  path.path = NULL;
330
  return path;
331 d8caf546 Priya
}
332 738e44fb Priya