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_, direction_);
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_, direction_);
140 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
143 void Elevator::transition_move_idle ()
146 // TODO: Call into the GUI to update the position
147 gui_update_position_label (number_, (float)position_, direction_);
148 // do not change position while IDLE
151 void Elevator::transition_open_door ()
153 /* Calculate the number of Stops above and below our
154 * current position */
155 StopList::const_iterator it;
156 Stop current = Stop(position_, direction_);
160 for (it = stops_.begin(); it != stops_.end(); it++)
169 /* If we are going to switch direction, clear all stops here,
170 * regardless of direction.
172 * Otherwise, just clear this stop */
173 if (direction_ == UP && stops_above == 0)
175 stops_.remove (Stop(position_, ALL));
176 gui_unpress_request_button (number_, (int)position_);
177 gui_unpress_call_button ((int)position_, UP);
178 gui_unpress_call_button ((int)position_, DOWN);
180 else if (direction_ == DOWN && stops_below == 0)
182 stops_.remove (Stop(position_, ALL));
183 gui_unpress_request_button (number_, (int)position_);
184 gui_unpress_call_button ((int)position_, UP);
185 gui_unpress_call_button ((int)position_, DOWN);
187 else if (direction_ == IDLE)
189 stops_.remove (Stop(position_, ALL));
190 gui_unpress_request_button (number_, (int)position_);
191 gui_unpress_call_button ((int)position_, UP);
192 gui_unpress_call_button ((int)position_, DOWN);
196 stops_.remove (Stop(position_, direction_));
197 gui_unpress_call_button ((int)position_, direction_);
198 gui_unpress_request_button (number_, (int)position_);
201 // TODO: Call into the GUI to open the door
202 gui_open_door (number_, (int)position_);
203 std::cout << "Opening Door" << std::endl;
206 void Elevator::transition_close_door ()
208 // TODO: Call into the GUI to close the door
209 gui_close_door (number_, (int)position_);
210 std::cout << "Closing Door" << std::endl;
213 void Elevator::transition_begin_wait ()
218 void Elevator::transition_continue_wait ()
224 static void debug (const std::string& s)
226 std::cout << s << std::endl;
229 static std::string get_state_name (State s)
236 sname = "STATE_IDLE";
242 sname = "STATE_DOWN";
245 sname = "STATE_WAIT";
247 case STATE_OPEN_DOOR:
248 sname = "STATE_OPEN_DOOR";
250 case STATE_CLOSE_DOOR:
251 sname = "STATE_CLOSE_DOOR";
261 static std::string get_event_name (Event e)
280 ename = "EVT_OPEN_DOOR";
283 ename = "EVT_CLOSE_DOOR";
293 static void bad_transition (State s, Event e)
295 std::cout << "Bad State Transition: " << get_state_name (s)
296 << " -> " << get_event_name (e) << std::endl;
299 Event Elevator::find_next_event () const
301 /* Calculate the number of Stops above and below our
302 * current position */
303 StopList::const_iterator it;
304 Stop current = Stop(position_, direction_);
308 for (it = stops_.begin(); it != stops_.end(); it++)
317 /* Now figure out which state transition to make */
322 if (currently_at_stop ())
323 return EVT_OPEN_DOOR;
336 if (currently_at_stop ())
337 return EVT_OPEN_DOOR;
344 if (currently_at_stop ())
345 return EVT_OPEN_DOOR;
355 return EVT_CLOSE_DOOR;
358 case STATE_OPEN_DOOR:
363 case STATE_CLOSE_DOOR:
365 if (currently_at_stop ())
366 return EVT_OPEN_DOOR;
368 if (direction_ == UP && stops_above > 0)
371 if (direction_ == DOWN && stops_below > 0)
374 /* We need to switch directions */
375 if (direction_ == UP && stops_above == 0 && stops_below > 0)
378 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
385 std::cout << "find_next_event(): Bad State" << std::endl;
390 void Elevator::move ()
392 /* Generate Events */
393 Event e = find_next_event ();
395 std::cout << "State Transition: " << get_state_name (state_) << " with "
396 << get_event_name (e) << std::endl;
405 transition_move_up ();
409 transition_move_down ();
413 transition_move_idle ();
416 state_ = STATE_OPEN_DOOR;
417 transition_open_door ();
420 bad_transition (state_, e);
430 transition_move_up ();
433 state_ = STATE_OPEN_DOOR;
434 transition_open_door ();
437 bad_transition (state_, e);
447 transition_move_down ();
450 state_ = STATE_OPEN_DOOR;
451 transition_open_door ();
454 bad_transition (state_, e);
464 transition_continue_wait ();
467 state_ = STATE_CLOSE_DOOR;
468 transition_close_door ();
471 bad_transition (state_, e);
476 case STATE_OPEN_DOOR:
481 transition_begin_wait ();
484 bad_transition (state_, e);
489 case STATE_CLOSE_DOOR:
493 state_ = STATE_OPEN_DOOR;
494 transition_open_door ();
498 transition_move_up ();
502 transition_move_down ();
506 transition_move_idle ();
509 bad_transition (state_, e);
515 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
520 bool Elevator::is_idle () const
522 if (stops_.size() != 0)
525 return direction_ == IDLE;
528 int Elevator::getLoad () const
530 return stops_.size ();
533 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */