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 this is an "ALL" Stop, it supercedes all others */
82 if (stop.getDirection() == ALL)
85 stops_.push_back (stop);
89 /* Check if this stop already exists. If so, just leave */
90 for (it = stops_.begin(); it != stops_.end(); it++)
94 /* The stop did not already exist, so add it */
95 stops_.push_back (stop);
98 float Elevator::distance_from (Position &pos) const
101 return position_ - pos;
103 return pos - position_;
106 float Elevator::distance_from (Stop &s) const
108 Direction d = s.getDirection();
109 Position p = s.getPosition ();
111 /* If direction doesn't matter, then only position does */
112 if (d == ALL || direction_ == IDLE)
113 return distance_from (p);
115 /* If we're not in the same direction, then we're "really far" away */
119 /* We must be in the correct direction, so pure distance is fine */
120 return distance_from (p);
123 void Elevator::transition_move_up ()
126 position_ += ELEVATOR_STEP;
128 // TODO: Call into the GUI to update the position
129 gui_update_position_label (number_, (float)position_);
130 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
133 void Elevator::transition_move_down ()
136 position_ -= ELEVATOR_STEP;
138 // TODO: Call into the GUI to update the position
139 gui_update_position_label (number_, (float)position_);
140 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
143 void Elevator::transition_move_idle ()
146 // do not change position while IDLE
149 void Elevator::transition_open_door ()
151 /* Calculate the number of Stops above and below our
152 * current position */
153 StopList::const_iterator it;
154 Stop current = Stop(position_, direction_);
158 for (it = stops_.begin(); it != stops_.end(); it++)
167 /* If we are going to switch direction, clear all stops here,
168 * regardless of direction.
170 * Otherwise, just clear this stop */
171 if (direction_ == UP && stops_above == 0)
173 stops_.remove (Stop(position_, ALL));
174 gui_unpress_request_button (number_, (int)position_);
175 gui_unpress_call_button ((int)position_, UP);
176 gui_unpress_call_button ((int)position_, DOWN);
178 else if (direction_ == DOWN && stops_below == 0)
180 stops_.remove (Stop(position_, ALL));
181 gui_unpress_request_button (number_, (int)position_);
182 gui_unpress_call_button ((int)position_, UP);
183 gui_unpress_call_button ((int)position_, DOWN);
185 else if (direction_ == IDLE)
187 stops_.remove (Stop(position_, ALL));
188 gui_unpress_request_button (number_, (int)position_);
189 gui_unpress_call_button ((int)position_, UP);
190 gui_unpress_call_button ((int)position_, DOWN);
194 stops_.remove (Stop(position_, direction_));
195 gui_unpress_call_button ((int)position_, direction_);
198 // TODO: Call into the GUI to open the door
199 gui_open_door (number_, (int)position_);
200 std::cout << "Opening Door" << std::endl;
203 void Elevator::transition_close_door ()
205 // TODO: Call into the GUI to close the door
206 gui_close_door (number_, (int)position_);
207 std::cout << "Closing Door" << std::endl;
210 void Elevator::transition_begin_wait ()
215 void Elevator::transition_continue_wait ()
221 static void debug (const std::string& s)
223 std::cout << s << std::endl;
226 static std::string get_state_name (State s)
233 sname = "STATE_IDLE";
239 sname = "STATE_DOWN";
242 sname = "STATE_WAIT";
244 case STATE_OPEN_DOOR:
245 sname = "STATE_OPEN_DOOR";
247 case STATE_CLOSE_DOOR:
248 sname = "STATE_CLOSE_DOOR";
258 static std::string get_event_name (Event e)
277 ename = "EVT_OPEN_DOOR";
280 ename = "EVT_CLOSE_DOOR";
290 static void bad_transition (State s, Event e)
292 std::cout << "Bad State Transition: " << get_state_name (s)
293 << " -> " << get_event_name (e) << std::endl;
296 Event Elevator::find_next_event () const
298 /* Calculate the number of Stops above and below our
299 * current position */
300 StopList::const_iterator it;
301 Stop current = Stop(position_, direction_);
305 for (it = stops_.begin(); it != stops_.end(); it++)
314 /* Now figure out which state transition to make */
319 if (currently_at_stop ())
320 return EVT_OPEN_DOOR;
333 if (currently_at_stop ())
334 return EVT_OPEN_DOOR;
341 if (currently_at_stop ())
342 return EVT_OPEN_DOOR;
352 return EVT_CLOSE_DOOR;
355 case STATE_OPEN_DOOR:
360 case STATE_CLOSE_DOOR:
362 if (currently_at_stop ())
363 return EVT_OPEN_DOOR;
365 if (direction_ == UP && stops_above > 0)
368 if (direction_ == DOWN && stops_below > 0)
371 /* We need to switch directions */
372 if (direction_ == UP && stops_above == 0 && stops_below > 0)
375 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
382 std::cout << "find_next_event(): Bad State" << std::endl;
387 void Elevator::move ()
389 /* Generate Events */
390 Event e = find_next_event ();
392 std::cout << "State Transition: " << get_state_name (state_) << " with "
393 << get_event_name (e) << std::endl;
402 transition_move_up ();
406 transition_move_down ();
410 transition_move_idle ();
413 state_ = STATE_OPEN_DOOR;
414 transition_open_door ();
417 bad_transition (state_, e);
427 transition_move_up ();
430 state_ = STATE_OPEN_DOOR;
431 transition_open_door ();
434 bad_transition (state_, e);
444 transition_move_down ();
447 state_ = STATE_OPEN_DOOR;
448 transition_open_door ();
451 bad_transition (state_, e);
461 transition_continue_wait ();
464 state_ = STATE_CLOSE_DOOR;
465 transition_close_door ();
468 bad_transition (state_, e);
473 case STATE_OPEN_DOOR:
478 transition_begin_wait ();
481 bad_transition (state_, e);
486 case STATE_CLOSE_DOOR:
490 state_ = STATE_OPEN_DOOR;
491 transition_open_door ();
495 transition_move_up ();
499 transition_move_down ();
503 transition_move_idle ();
506 bad_transition (state_, e);
512 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
517 bool Elevator::is_idle () const
519 return direction_ == IDLE;
522 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */