1 #include "elevator.hpp"
4 Elevator::Elevator (int elevator_number)
10 , number_(elevator_number)
12 // Intentionally Left Empty
15 Elevator::Elevator (int starting_floor, int elevator_number)
19 , position_(starting_floor)
21 , number_(elevator_number)
23 // Intentionally Left Empty
26 bool Elevator::currently_at_stop () const
28 StopList::const_iterator it;
29 Stop current(position_, direction_);
31 /* Calculate the number of Stops above and below our current position */
35 for (it = stops_.begin(); it != stops_.end(); it++)
44 /* Check if we are at the top. If so, only the position needs to match */
45 if (direction_ == UP && stops_above == 0)
47 for (it = stops_.begin (); it != stops_.end (); it++)
48 if (it->getPosition() == position_)
52 /* Check if we are at the bottom. If so, only the position needs to match */
53 if (direction_ == DOWN && stops_below == 0)
55 for (it = stops_.begin (); it != stops_.end (); it++)
56 if (it->getPosition() == position_)
60 /* Check if we match exactly */
61 for (it = stops_.begin (); it != stops_.end (); it++)
65 /* Check if we are IDLE. If so, only the position needs to match */
66 if (direction_ == IDLE)
68 for (it = stops_.begin (); it != stops_.end (); it++)
69 if (it->getPosition() == position_)
77 void Elevator::stop_at (Stop &stop)
79 StopList::iterator it;
81 if (stop.getDirection() == IDLE)
82 throw bad_direction();
84 /* If this is an "ALL" Stop, it supercedes all others */
85 if (stop.getDirection() == ALL)
88 stops_.push_back (stop);
93 /* Check if this stop already exists. If so, just leave */
94 for (it = stops_.begin(); it != stops_.end(); it++)
98 /* The stop did not already exist, so add it */
99 stops_.push_back (stop);
102 float Elevator::distance_from (Position &pos) const
105 return position_ - pos;
107 return pos - position_;
110 float Elevator::distance_from (Stop &s) const
112 Direction d = s.getDirection();
113 Position p = s.getPosition ();
115 /* If direction doesn't matter, then only position does */
116 if (d == ALL || direction_ == IDLE)
117 return distance_from (p);
119 /* If we're not in the same direction, then we're "really far" away */
123 /* We must be in the correct direction, so pure distance is fine */
124 return distance_from (p);
127 void Elevator::transition_move_up ()
130 position_ += ELEVATOR_STEP;
132 // TODO: Call into the GUI to update the position
133 gui_update_position_label (number_, (float)position_, direction_);
134 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
137 void Elevator::transition_move_down ()
140 position_ -= ELEVATOR_STEP;
142 // TODO: Call into the GUI to update the position
143 gui_update_position_label (number_, (float)position_, direction_);
144 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
147 void Elevator::transition_move_idle ()
150 // TODO: Call into the GUI to update the position
151 gui_update_position_label (number_, (float)position_, direction_);
152 // do not change position while IDLE
155 void Elevator::transition_open_door ()
157 /* Calculate the number of Stops above and below our
158 * current position */
159 StopList::const_iterator it;
160 Stop current = Stop(position_, direction_);
164 for (it = stops_.begin(); it != stops_.end(); it++)
173 std::cout << "Elevator: " << number_ << " stopping in direction=" << direction_ << std::endl;
175 /* Always unpress the in-elevator button for this stop, as well
176 * as clear the stop. This is like letting people off at a floor. */
177 gui_unpress_request_button (number_, (int)position_);
178 stops_.remove (Stop(position_, ALL));
181 /* If we are going to switch direction, clear all stops here,
182 * regardless of direction.
184 * Otherwise, just clear this stop */
185 if (direction_ == UP && stops_above == 0)
187 stops_.remove (Stop(position_, UP));
188 stops_.remove (Stop(position_, DOWN));
189 gui_unpress_call_button ((int)position_, UP);
190 gui_unpress_call_button ((int)position_, DOWN);
192 else if (direction_ == DOWN && stops_below == 0)
194 stops_.remove (Stop(position_, UP));
195 stops_.remove (Stop(position_, DOWN));
196 gui_unpress_call_button ((int)position_, UP);
197 gui_unpress_call_button ((int)position_, DOWN);
199 else if (direction_ == IDLE)
201 stops_.remove (Stop(position_, UP));
202 stops_.remove (Stop(position_, DOWN));
203 gui_unpress_call_button ((int)position_, UP);
204 gui_unpress_call_button ((int)position_, DOWN);
208 stops_.remove (Stop(position_, direction_));
209 gui_unpress_call_button ((int)position_, direction_);
212 // TODO: Call into the GUI to open the door
213 gui_open_door (number_, (int)position_);
214 std::cout << "Opening Door" << std::endl;
217 void Elevator::transition_close_door ()
219 // TODO: Call into the GUI to close the door
220 gui_close_door (number_, (int)position_);
221 std::cout << "Closing Door" << std::endl;
224 void Elevator::transition_begin_wait ()
229 void Elevator::transition_continue_wait ()
235 static void debug (const std::string& s)
237 std::cout << s << std::endl;
240 static std::string get_state_name (State s)
247 sname = "STATE_IDLE";
253 sname = "STATE_DOWN";
256 sname = "STATE_WAIT";
258 case STATE_OPEN_DOOR:
259 sname = "STATE_OPEN_DOOR";
261 case STATE_CLOSE_DOOR:
262 sname = "STATE_CLOSE_DOOR";
272 static std::string get_event_name (Event e)
291 ename = "EVT_OPEN_DOOR";
294 ename = "EVT_CLOSE_DOOR";
304 static void bad_transition (State s, Event e)
306 std::cout << "Bad State Transition: " << get_state_name (s)
307 << " -> " << get_event_name (e) << std::endl;
310 Event Elevator::find_next_event () const
312 /* Calculate the number of Stops above and below our
313 * current position */
314 StopList::const_iterator it;
315 Stop current = Stop(position_, direction_);
319 for (it = stops_.begin(); it != stops_.end(); it++)
328 /* Now figure out which state transition to make */
333 if (currently_at_stop ())
334 return EVT_OPEN_DOOR;
347 if (currently_at_stop ())
348 return EVT_OPEN_DOOR;
355 if (currently_at_stop ())
356 return EVT_OPEN_DOOR;
366 return EVT_CLOSE_DOOR;
369 case STATE_OPEN_DOOR:
374 case STATE_CLOSE_DOOR:
376 if (currently_at_stop ())
377 return EVT_OPEN_DOOR;
379 if (direction_ == UP && stops_above > 0)
382 if (direction_ == DOWN && stops_below > 0)
385 /* We need to switch directions */
386 if (direction_ == UP && stops_above == 0 && stops_below > 0)
389 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
396 std::cout << "find_next_event(): Bad State" << std::endl;
401 void Elevator::move ()
403 /* Generate Events */
404 Event e = find_next_event ();
406 std::cout << "State Transition: " << get_state_name (state_) << " with "
407 << get_event_name (e) << std::endl;
416 transition_move_up ();
420 transition_move_down ();
424 transition_move_idle ();
427 state_ = STATE_OPEN_DOOR;
428 transition_open_door ();
431 bad_transition (state_, e);
441 transition_move_up ();
444 state_ = STATE_OPEN_DOOR;
445 transition_open_door ();
448 bad_transition (state_, e);
458 transition_move_down ();
461 state_ = STATE_OPEN_DOOR;
462 transition_open_door ();
465 bad_transition (state_, e);
475 transition_continue_wait ();
478 state_ = STATE_CLOSE_DOOR;
479 transition_close_door ();
482 bad_transition (state_, e);
487 case STATE_OPEN_DOOR:
492 transition_begin_wait ();
495 bad_transition (state_, e);
500 case STATE_CLOSE_DOOR:
504 state_ = STATE_OPEN_DOOR;
505 transition_open_door ();
509 transition_move_up ();
513 transition_move_down ();
517 transition_move_idle ();
520 bad_transition (state_, e);
526 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
531 bool Elevator::is_idle () const
533 if (stops_.size() != 0)
536 return direction_ == IDLE;
539 int Elevator::getLoad () const
541 return stops_.size ();
544 bool Elevator::willStopAt (int floor, Direction direction) const
546 Stop s (floor, direction);
547 StopList::const_iterator it;
549 for (it=stops_.begin(); it != stops_.end(); it++)
556 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */