1 #include "elevator.hpp"
3 Elevator::Elevator (int elevator_number)
9 , number_(elevator_number)
11 // Intentionally Left Empty
14 Elevator::Elevator (int starting_floor, int elevator_number)
18 , position_(starting_floor)
20 , number_(elevator_number)
22 // Intentionally Left Empty
25 bool Elevator::currently_at_stop () const
27 StopList::const_iterator it;
28 Stop current(position_, direction_);
30 /* Calculate the number of Stops above and below our current position */
34 for (it = stops_.begin(); it != stops_.end(); it++)
43 /* Check if we are at the top. If so, only the position needs to match */
44 if (direction_ == UP && stops_above == 0)
46 for (it = stops_.begin (); it != stops_.end (); it++)
47 if (it->getPosition() == position_)
51 /* Check if we are at the bottom. If so, only the position needs to match */
52 if (direction_ == DOWN && stops_below == 0)
54 for (it = stops_.begin (); it != stops_.end (); it++)
55 if (it->getPosition() == position_)
59 /* Check if we match exactly */
60 for (it = stops_.begin (); it != stops_.end (); it++)
68 void Elevator::stop_at (Stop &stop)
70 StopList::iterator it;
72 /* If this is an "ALL" Stop, it supercedes all others */
73 if (stop.getDirection() == ALL)
76 stops_.push_back (stop);
80 /* Check if this stop already exists. If so, just leave */
81 for (it = stops_.begin(); it != stops_.end(); it++)
85 /* The stop did not already exist, so add it */
86 stops_.push_back (stop);
89 float Elevator::distance_from (Position &pos) const
92 return position_ - pos;
94 return pos - position_;
97 float Elevator::distance_from (Stop &s) const
99 Direction d = s.getDirection();
100 Position p = s.getPosition ();
102 /* If direction doesn't matter, then only position does */
103 if (d == ALL || direction_ == IDLE)
104 return distance_from (p);
106 /* If we're not in the same direction, then we're "really far" away */
110 /* We must be in the correct direction, so pure distance is fine */
111 return distance_from (p);
114 void Elevator::transition_move_up ()
117 position_ += ELEVATOR_STEP;
119 // TODO: Call into the GUI to update the position
120 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
123 void Elevator::transition_move_down ()
126 position_ -= ELEVATOR_STEP;
128 // TODO: Call into the GUI to update the position
129 std::cout << "Updating the GUI with our position: " << position_ << std::endl;
132 void Elevator::transition_move_idle ()
135 // do not change position while IDLE
138 void Elevator::transition_open_door ()
140 /* Calculate the number of Stops above and below our
141 * current position */
142 StopList::const_iterator it;
143 Stop current = Stop(position_, direction_);
147 for (it = stops_.begin(); it != stops_.end(); it++)
156 /* If we are going to switch direction, clear all stops here,
157 * regardless of direction.
159 * Otherwise, just clear this stop */
160 if (direction_ == UP && stops_above == 0)
161 stops_.remove (Stop(position_, ALL));
162 else if (direction_ == DOWN && stops_below == 0)
163 stops_.remove (Stop(position_, ALL));
165 stops_.remove (Stop(position_, direction_));
167 // TODO: Call into the GUI to open the door
168 std::cout << "Opening Door" << std::endl;
171 void Elevator::transition_close_door ()
173 // TODO: Call into the GUI to close the door
174 std::cout << "Closing Door" << std::endl;
177 void Elevator::transition_begin_wait ()
182 void Elevator::transition_continue_wait ()
188 static void debug (const std::string& s)
190 std::cout << s << std::endl;
193 static std::string get_state_name (State s)
200 sname = "STATE_IDLE";
206 sname = "STATE_DOWN";
209 sname = "STATE_WAIT";
211 case STATE_OPEN_DOOR:
212 sname = "STATE_OPEN_DOOR";
214 case STATE_CLOSE_DOOR:
215 sname = "STATE_CLOSE_DOOR";
225 static std::string get_event_name (Event e)
244 ename = "EVT_OPEN_DOOR";
247 ename = "EVT_CLOSE_DOOR";
257 static void bad_transition (State s, Event e)
259 std::cout << "Bad State Transition: " << get_state_name (s)
260 << " -> " << get_event_name (e) << std::endl;
263 Event Elevator::find_next_event () const
265 /* Calculate the number of Stops above and below our
266 * current position */
267 StopList::const_iterator it;
268 Stop current = Stop(position_, direction_);
272 for (it = stops_.begin(); it != stops_.end(); it++)
281 /* Now figure out which state transition to make */
286 if (currently_at_stop ())
287 return EVT_OPEN_DOOR;
300 if (currently_at_stop ())
301 return EVT_OPEN_DOOR;
308 if (currently_at_stop ())
309 return EVT_OPEN_DOOR;
319 return EVT_CLOSE_DOOR;
322 case STATE_OPEN_DOOR:
327 case STATE_CLOSE_DOOR:
329 if (currently_at_stop ())
330 return EVT_OPEN_DOOR;
332 if (direction_ == UP && stops_above > 0)
335 if (direction_ == DOWN && stops_below > 0)
338 /* We need to switch directions */
339 if (direction_ == UP && stops_above == 0 && stops_below > 0)
342 if (direction_ == DOWN && stops_below == 0 && stops_above > 0)
349 std::cout << "find_next_event(): Bad State" << std::endl;
354 void Elevator::move ()
356 /* Generate Events */
357 Event e = find_next_event ();
359 std::cout << "State Transition: " << get_state_name (state_) << " with "
360 << get_event_name (e) << std::endl;
369 transition_move_up ();
373 transition_move_down ();
377 transition_move_idle ();
380 state_ = STATE_OPEN_DOOR;
381 transition_open_door ();
384 bad_transition (state_, e);
394 transition_move_up ();
397 state_ = STATE_OPEN_DOOR;
398 transition_open_door ();
401 bad_transition (state_, e);
411 transition_move_down ();
414 state_ = STATE_OPEN_DOOR;
415 transition_open_door ();
418 bad_transition (state_, e);
428 transition_continue_wait ();
431 state_ = STATE_CLOSE_DOOR;
432 transition_close_door ();
435 bad_transition (state_, e);
440 case STATE_OPEN_DOOR:
445 transition_begin_wait ();
448 bad_transition (state_, e);
453 case STATE_CLOSE_DOOR:
457 state_ = STATE_OPEN_DOOR;
458 transition_open_door ();
462 transition_move_up ();
466 transition_move_down ();
470 transition_move_idle ();
473 bad_transition (state_, e);
479 std::cout << "Bad State: " << get_state_name (state_) << std::endl;
484 bool Elevator::is_idle () const
486 return direction_ == IDLE;
489 /* vim: set ts=4 sts=4 sw=4 noexpandtab textwidth=112: */