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_);
196 gui_unpress_request_button (number_, (int)position_);
199 // TODO: Call into the GUI to open the door
200 gui_open_door (number_, (int)position_);
201 std::cout << "Opening Door" << std::endl;
204 void Elevator::transition_close_door ()
206 // TODO: Call into the GUI to close the door
207 gui_close_door (number_, (int)position_);
208 std::cout << "Closing Door" << std::endl;
211 void Elevator::transition_begin_wait ()
216 void Elevator::transition_continue_wait ()
222 static void debug (const std::string& s)
224 std::cout << s << std::endl;
227 static std::string get_state_name (State s)
234 sname = "STATE_IDLE";
240 sname = "STATE_DOWN";
243 sname = "STATE_WAIT";
245 case STATE_OPEN_DOOR:
246 sname = "STATE_OPEN_DOOR";
248 case STATE_CLOSE_DOOR:
249 sname = "STATE_CLOSE_DOOR";
259 static std::string get_event_name (Event e)
278 ename = "EVT_OPEN_DOOR";
281 ename = "EVT_CLOSE_DOOR";
291 static void bad_transition (State s, Event e)
293 std::cout << "Bad State Transition: " << get_state_name (s)
294 << " -> " << get_event_name (e) << std::endl;
297 Event Elevator::find_next_event () const
299 /* Calculate the number of Stops above and below our
300 * current position */
301 StopList::const_iterator it;
302 Stop current = Stop(position_, direction_);
306 for (it = stops_.begin(); it != stops_.end(); it++)
315 /* Now figure out which state transition to make */
320 if (currently_at_stop ())
321 return EVT_OPEN_DOOR;
334 if (currently_at_stop ())
335 return EVT_OPEN_DOOR;
342 if (currently_at_stop ())
343 return EVT_OPEN_DOOR;
353 return EVT_CLOSE_DOOR;
356 case STATE_OPEN_DOOR:
361 case STATE_CLOSE_DOOR:
363 if (currently_at_stop ())
364 return EVT_OPEN_DOOR;
366 if (direction_ == UP && stops_above > 0)
369 if (direction_ == DOWN && stops_below > 0)
372 /* We need to switch directions */
373 if (direction_ == UP && stops_above == 0 && stops_below > 0)
376 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
383 std::cout << "find_next_event(): Bad State" << std::endl;
388 void Elevator::move ()
390 /* Generate Events */
391 Event e = find_next_event ();
393 std::cout << "State Transition: " << get_state_name (state_) << " with "
394 << get_event_name (e) << std::endl;
403 transition_move_up ();
407 transition_move_down ();
411 transition_move_idle ();
414 state_ = STATE_OPEN_DOOR;
415 transition_open_door ();
418 bad_transition (state_, e);
428 transition_move_up ();
431 state_ = STATE_OPEN_DOOR;
432 transition_open_door ();
435 bad_transition (state_, e);
445 transition_move_down ();
448 state_ = STATE_OPEN_DOOR;
449 transition_open_door ();
452 bad_transition (state_, e);
462 transition_continue_wait ();
465 state_ = STATE_CLOSE_DOOR;
466 transition_close_door ();
469 bad_transition (state_, e);
474 case STATE_OPEN_DOOR:
479 transition_begin_wait ();
482 bad_transition (state_, e);
487 case STATE_CLOSE_DOOR:
491 state_ = STATE_OPEN_DOOR;
492 transition_open_door ();
496 transition_move_up ();
500 transition_move_down ();
504 transition_move_idle ();
507 bad_transition (state_, e);
513 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
518 bool Elevator::is_idle () const
520 return direction_ == IDLE;
523 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */