Subversion Repositories programming

Rev

Rev 335 | Rev 338 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
321 ira 1
 
2
#include "controller.h"
3
 
4
Controller::Controller (int num_floors, int num_elevators) : num_floors (num_floors), num_elevators (num_elevators)
5
{
6
    assert (num_floors > 2);
7
    assert (num_elevators > 0);
8
 
334 ira 9
    elevator.reserve (num_elevators);
331 ira 10
 
11
    for (int i=0; i<num_elevators; i++)
332 ira 12
    {
334 ira 13
        elevator.push_back (new Elevator (num_floors));
14
        elevator.at(i) -> set_controller (this);
332 ira 15
    }
335 ira 16
 
17
    // Seed the RNG
18
    srandom (time(NULL));
321 ira 19
}
20
 
21
Controller::~Controller ()
22
{
23
}
24
 
329 ira 25
void Controller::request_elevator (int on_floor, int direction)
321 ira 26
{
334 ira 27
    assert (on_floor < num_floors);
28
    assert (on_floor >= 0);
331 ira 29
    assert (direction == MOVE_UP || direction == MOVE_DOWN);
328 ira 30
 
31
    float distance = INT_MAX;
32
    int elevator_number;
33
 
34
    // check that there is not already an elevator requested
35
    // to this floor. If there is already one, ignore this
36
    // request.
37
    if (floor_already_requested (on_floor))
38
        return;
39
 
40
    // find elevator that is closest, AND NOT moving away
41
    // "push" it's button
332 ira 42
    elevator_number = find_closest_elevator (on_floor, direction);
334 ira 43
    elevator.at(elevator_number) -> push_button (on_floor);
332 ira 44
 
45
    printf ("elevator[%d] gets queued for floor: %d\n", elevator_number, on_floor);
321 ira 46
}
47
 
328 ira 48
/**
49
 * Check if there is an elevator already in the queue to stop
50
 * at the floor given as a parameter.
51
 */
52
bool Controller::floor_already_requested (int on_floor)
53
{
336 ira 54
    assert (on_floor >= 0);
55
    assert (on_floor < num_floors);
56
 
328 ira 57
    int i;
58
 
59
    for (i=0; i<num_elevators; i++)
334 ira 60
        if (elevator.at(i) -> button_is_pushed (on_floor))
328 ira 61
            return true;
62
 
63
    return false;
64
}
65
 
66
/**
67
 * Return the number of the closest elevator to the
68
 * floor given as a parameter.
69
 *
70
 * We only want to choose elevators that are close and
71
 * heading in the right direction, or the closest elevator
72
 * if it is sitting idle.
73
 */
332 ira 74
int Controller::find_closest_elevator (int to_floor, int in_direction)
328 ira 75
{
336 ira 76
    assert (to_floor >= 0);
77
    assert (to_floor < num_floors);
78
    assert (in_direction == MOVE_UP || in_direction == MOVE_DOWN);
79
 
328 ira 80
    int i;
81
    float distance = INT_MAX;
82
    float temp_distance;
335 ira 83
    int answer = -1;
328 ira 84
 
85
    float cur_floor;
335 ira 86
    int   cur_direction;
328 ira 87
 
335 ira 88
    printf ("finding closest elevator: to_floor=%d -- in_direction=%d\n", to_floor, in_direction);
89
 
328 ira 90
    for (i=0; i<num_elevators; i++)
91
    {
334 ira 92
        cur_floor = elevator.at(i) -> get_current_floor ();
335 ira 93
        cur_direction = elevator.at(i) -> get_direction ();
328 ira 94
        temp_distance = fabsf (cur_floor - to_floor);
95
 
335 ira 96
        printf ("cur_floor=%e -- direc=%d -- t_dist=%e\n", cur_floor, cur_direction, temp_distance);
334 ira 97
 
332 ira 98
        // Automatically discard elevators that are moving in the wrong
99
        // direction, but DO consider ones that are idle.
335 ira 100
        if (cur_direction == MOVE_DOWN && in_direction == MOVE_UP)
101
        {
102
            printf ("type 1: skipped elevator[%d]\n", i);
332 ira 103
            continue;
335 ira 104
        }
332 ira 105
 
335 ira 106
        if (cur_direction == MOVE_UP && in_direction == MOVE_DOWN)
107
        {
108
            printf ("type 2: skipped elevator[%d]\n", i);
334 ira 109
            continue;
335 ira 110
        }
334 ira 111
 
335 ira 112
        if (cur_floor < to_floor && cur_direction == MOVE_UP)
328 ira 113
        {
335 ira 114
            printf ("good cantidate type 1\n");
115
            // GOOD CANTIDATE
116
            if (temp_distance < distance)
328 ira 117
            {
118
                answer = i;
119
                distance = temp_distance;
120
            }
335 ira 121
        }
122
 
123
        if (cur_floor > to_floor && cur_direction == MOVE_DOWN)
124
        {
125
            printf ("good cantidate type 2\n");
126
            // GOOD CANTIDATE
127
            if (temp_distance < distance)
328 ira 128
            {
129
                answer = i;
130
                distance = temp_distance;
131
            }
132
        }
335 ira 133
 
134
        if (cur_direction == IDLE && temp_distance < distance)
135
        {
136
            printf ("idle cantidate\n");
137
            answer = i;
138
            distance = temp_distance;
139
        }
328 ira 140
    }
141
 
335 ira 142
    // If we failed to find an elevator, then we need to
143
    // pick at random.
144
    if (answer == -1)
145
    {
146
        // Pick a random number in the range [0,num_elevators-1]
147
        answer = (int) (0.0 + ((num_elevators - 1.0) * (random() / (RAND_MAX + 1.0))));
148
 
149
        printf ("picked at random: %d\n", answer);
150
 
151
        assert (answer >= 0);
152
        assert (answer < num_elevators);
153
    }
154
 
328 ira 155
    return answer;
156
}
157
 
329 ira 158
void Controller::disable_elevator (int elevator_number)
159
{
160
}
161
 
162
void Controller::enable_elevator (int elevator_number)
163
{
164
    // make sure elevator is enabled first
165
}
166
 
331 ira 167
void Controller::start_all_elevators ()
168
{
169
    int i;
170
 
171
    for (i=0; i<num_elevators; i++)
334 ira 172
        elevator.at(i) -> thread_start ();
331 ira 173
}
174
 
175
void Controller::stop_all_elevators ()
176
{
177
    int i;
178
 
179
    for (i=0; i<num_elevators; i++)
334 ira 180
        elevator.at(i) -> thread_stop ();
331 ira 181
}
182
 
183
void Controller::pause_all_elevators ()
184
{
185
    int i;
186
 
187
    for (i=0; i<num_elevators; i++)
334 ira 188
        elevator.at(i) -> thread_pause ();
331 ira 189
}
190
 
191
void Controller::unpause_all_elevators ()
192
{
193
    int i;
194
 
195
    for (i=0; i<num_elevators; i++)
334 ira 196
        elevator.at(i) -> thread_unpause ();
331 ira 197
}
198
 
334 ira 199