1 #include "elevator.hpp"
10 // Intentionally Left Empty
13 Elevator::Elevator (int starting_floor)
17 , position_(starting_floor)
20 // Intentionally Left Empty
23 bool Elevator::currently_at_stop () const
25 StopList::const_iterator it;
26 Stop current(position_, direction_);
28 /* Calculate the number of Stops above and below our current position */
32 for (it = stops_.begin(); it != stops_.end(); it++)
41 /* Check if we are at the top. If so, only the position needs to match */
42 if (direction_ == UP && stops_above == 0)
44 for (it = stops_.begin (); it != stops_.end (); it++)
45 if (it->getPosition() == position_)
49 /* Check if we are at the bottom. If so, only the position needs to match */
50 if (direction_ == DOWN && stops_below == 0)
52 for (it = stops_.begin (); it != stops_.end (); it++)
53 if (it->getPosition() == position_)
57 /* Check if we match exactly */
58 for (it = stops_.begin (); it != stops_.end (); it++)
66 void Elevator::stop_at (Stop &stop)
68 StopList::iterator it;
70 /* If this is an "ALL" Stop, it supercedes all others */
71 if (stop.getDirection() == ALL)
74 stops_.push_back (stop);
78 /* Check if this stop already exists. If so, just leave */
79 for (it = stops_.begin(); it != stops_.end(); it++)
83 /* The stop did not already exist, so add it */
84 stops_.push_back (stop);
87 float Elevator::distance_from (Position &pos) const
90 return position_ - pos;
92 return pos - position_;
95 float Elevator::distance_from (Stop &s) const
97 Direction d = s.getDirection();
98 Position p = s.getPosition ();
100 /* If direction doesn't matter, then only position does */
101 if (d == ALL || direction_ == IDLE)
102 return distance_from (p);
104 /* If we're not in the same direction, then we're "really far" away */
108 /* We must be in the correct direction, so pure distance is fine */
109 return distance_from (p);
112 void Elevator::transition_move_up ()
115 position_ += ELEVATOR_STEP;
117 // TODO: Call into the GUI to update the position
118 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
121 void Elevator::transition_move_down ()
124 position_ -= ELEVATOR_STEP;
126 // TODO: Call into the GUI to update the position
127 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
130 void Elevator::transition_move_idle ()
133 // do not change position while IDLE
136 void Elevator::transition_open_door ()
138 /* Calculate the number of Stops above and below our
139 * current position */
140 StopList::const_iterator it;
141 Stop current = Stop(position_, direction_);
145 for (it = stops_.begin(); it != stops_.end(); it++)
154 /* If we are going to switch direction, clear all stops here,
155 * regardless of direction.
157 * Otherwise, just clear this stop */
158 if (direction_ == UP && stops_above == 0)
159 stops_.remove (Stop(position_, ALL));
160 else if (direction_ == DOWN && stops_below == 0)
161 stops_.remove (Stop(position_, ALL));
163 stops_.remove (Stop(position_, direction_));
165 // TODO: Call into the GUI to open the door
166 std::cout << "Opening Door" << std::endl;
169 void Elevator::transition_close_door ()
171 // TODO: Call into the GUI to close the door
172 std::cout << "Closing Door" << std::endl;
175 void Elevator::transition_begin_wait ()
180 void Elevator::transition_continue_wait ()
186 static void debug (const std::string& s)
188 std::cout << s << std::endl;
191 static std::string get_state_name (State s)
198 sname = "STATE_IDLE";
204 sname = "STATE_DOWN";
207 sname = "STATE_WAIT";
209 case STATE_OPEN_DOOR:
210 sname = "STATE_OPEN_DOOR";
212 case STATE_CLOSE_DOOR:
213 sname = "STATE_CLOSE_DOOR";
223 static std::string get_event_name (Event e)
242 ename = "EVT_OPEN_DOOR";
245 ename = "EVT_CLOSE_DOOR";
255 static void bad_transition (State s, Event e)
257 std::cout << "Bad State Transition: " << get_state_name (s)
258 << " -> " << get_event_name (e) << std::endl;
261 Event Elevator::find_next_event () const
263 /* Calculate the number of Stops above and below our
264 * current position */
265 StopList::const_iterator it;
266 Stop current = Stop(position_, direction_);
270 for (it = stops_.begin(); it != stops_.end(); it++)
279 /* Now figure out which state transition to make */
284 if (currently_at_stop ())
285 return EVT_OPEN_DOOR;
298 if (currently_at_stop ())
299 return EVT_OPEN_DOOR;
306 if (currently_at_stop ())
307 return EVT_OPEN_DOOR;
317 return EVT_CLOSE_DOOR;
320 case STATE_OPEN_DOOR:
325 case STATE_CLOSE_DOOR:
327 if (currently_at_stop ())
328 return EVT_OPEN_DOOR;
330 if (direction_ == UP && stops_above > 0)
333 if (direction_ == DOWN && stops_below > 0)
336 /* We need to switch directions */
337 if (direction_ == UP && stops_above == 0 && stops_below > 0)
340 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
347 std::cout << "find_next_event(): Bad State" << std::endl;
352 void Elevator::move ()
354 /* Generate Events */
355 Event e = find_next_event ();
357 std::cout << "State Transition: " << get_state_name (state_) << " with "
358 << get_event_name (e) << std::endl;
367 transition_move_up ();
371 transition_move_down ();
375 transition_move_idle ();
378 state_ = STATE_OPEN_DOOR;
379 transition_open_door ();
382 bad_transition (state_, e);
392 transition_move_up ();
395 state_ = STATE_OPEN_DOOR;
396 transition_open_door ();
399 bad_transition (state_, e);
409 transition_move_down ();
412 state_ = STATE_OPEN_DOOR;
413 transition_open_door ();
416 bad_transition (state_, e);
426 transition_continue_wait ();
429 state_ = STATE_CLOSE_DOOR;
430 transition_close_door ();
433 bad_transition (state_, e);
438 case STATE_OPEN_DOOR:
443 transition_begin_wait ();
446 bad_transition (state_, e);
451 case STATE_CLOSE_DOOR:
455 state_ = STATE_OPEN_DOOR;
456 transition_open_door ();
460 transition_move_up ();
464 transition_move_down ();
468 transition_move_idle ();
471 bad_transition (state_, e);
477 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
482 bool Elevator::is_idle () const
484 return direction_ == IDLE;
487 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */