scoutos / scout / libscout / src / behaviors / Scheduler.cpp @ 1905324e
History | View | Annotate | Download (5.54 KB)
1 | 97b6298e | unknown | #include "Scheduler.h" |
---|---|---|---|
2 | 2f025967 | Priya | #include "../helper_classes/Order.h" |
3 | 97b6298e | unknown | |
4 | using namespace std; |
||
5 | |||
6 | /** @Brief: Initialize data structures for the scheduler. */
|
||
7 | 2f025967 | Priya | Scheduler::Scheduler(std::string scoutname):Behavior(scoutname, "Scheduler") |
8 | 97b6298e | unknown | { |
9 | 2f025967 | Priya | unassignedOrders = new PQWrapper(NUM_TASKS);
|
10 | |||
11 | 97b6298e | unknown | create_orders(); |
12 | } |
||
13 | |||
14 | /** @Brief: Free allocatetd memory. */
|
||
15 | Scheduler::~Scheduler() |
||
16 | { |
||
17 | 3f72678f | Priya | delete unassignedOrders;
|
18 | 97b6298e | unknown | } |
19 | |||
20 | 76cefba1 | Priya | /** @Brief: Add robot to the waiting queue.
|
21 | * A robot calls this function with itself
|
||
22 | * and gets pushed on a list of waiting robots.
|
||
23 | * When a task is availaible the scheduler, removes
|
||
24 | * the robot of the waiting queue, and gives it a
|
||
25 | * task.
|
||
26 | */
|
||
27 | 3f72678f | Priya | void Scheduler::get_task(int robot) |
28 | 97b6298e | unknown | { |
29 | ad5b5826 | Priya | Robot my_robot = robots[robot-1];
|
30 | if(my_robot.sched_status != WAITING_ROBOT)
|
||
31 | { |
||
32 | waitingRobots.push(my_robot); |
||
33 | my_robot.sched_status = WAITING_ROBOT; |
||
34 | } |
||
35 | 97b6298e | unknown | } |
36 | |||
37 | /** @Brief: Statically add orders to the Priority Queue Wrapper.*/
|
||
38 | void Scheduler::create_orders()
|
||
39 | { |
||
40 | 2f025967 | Priya | Path p; |
41 | p.len = 0;
|
||
42 | p.path = NULL;
|
||
43 | Time t = ros::Time::now(); |
||
44 | Duration end(0);
|
||
45 | 5d0687a9 | Priya | Duration five(5);
|
46 | Duration three(3);
|
||
47 | Duration ten(10);
|
||
48 | 1905324e | Priya | Order a(1,0,2,t+ten,p,end); |
49 | Order b(2,0,4,t+five,p,end); |
||
50 | Order c(3,0,5,t+three,p,end); |
||
51 | Order d(4,0,6,t,p,end); |
||
52 | Order e(5,0,7,t,p,end); |
||
53 | 97b6298e | unknown | |
54 | 2f025967 | Priya | unassignedOrders->insert(a); |
55 | unassignedOrders->insert(b); |
||
56 | unassignedOrders->insert(c); |
||
57 | unassignedOrders->insert(d); |
||
58 | unassignedOrders->insert(e); |
||
59 | 97b6298e | unknown | } |
60 | |||
61 | /** @Brief: This is a confirmation that the task is complete.
|
||
62 | This function removes the order from assignedOrders. */
|
||
63 | void Scheduler::task_complete(Order o)
|
||
64 | { |
||
65 | 3f72678f | Priya | ROS_INFO("Scheduler: Task id %d was completed", o.getid());
|
66 | for (unsigned int i=0; i<assignedOrders.size(); i++) |
||
67 | { |
||
68 | if (assignedOrders[i].getid()==o.getid())
|
||
69 | { |
||
70 | assignedOrders.erase(assignedOrders.begin()+i); |
||
71 | } |
||
72 | } |
||
73 | 97b6298e | unknown | } |
74 | |||
75 | /** @Brief: This is a confirmation that the task failed.
|
||
76 | This function places the order back on the PQWrapper. */
|
||
77 | void Scheduler::task_failed(Order o)
|
||
78 | { |
||
79 | 3f72678f | Priya | ROS_INFO("Scheduler: Task id %d was failed", o.getid());
|
80 | 97b6298e | unknown | task_complete(o); |
81 | 2f025967 | Priya | unassignedOrders->insert(o); |
82 | 97b6298e | unknown | } |
83 | |||
84 | /** @Brief: Do a waiting dance. */
|
||
85 | void Scheduler::waiting_dance()
|
||
86 | 3f72678f | Priya | { |
87 | ad5b5826 | Priya | //ROS_INFO("Scheduler: TEEHEE i do a dance!");
|
88 | 97b6298e | unknown | } |
89 | |||
90 | /** @Brief: The scheduling algorithm. Picks a task and pops from the PQWrapper. */
|
||
91 | Order Scheduler::get_next_item() |
||
92 | { |
||
93 | 2f025967 | Priya | Time t = ros::TIME_MAX; |
94 | double time = t.toSec();
|
||
95 | 76cefba1 | Priya | |
96 | 2f025967 | Priya | Order* best; |
97 | 5d0687a9 | Priya | int best_index;
|
98 | dc742c14 | Alex | for(unsigned int i=0; i<unassignedOrders->arraySize(); i++) |
99 | 76cefba1 | Priya | { |
100 | 2f025967 | Priya | Order order = unassignedOrders->peek(i); |
101 | |||
102 | Time end_time = order.get_start_time() - order.get_est_time(); |
||
103 | 76cefba1 | Priya | |
104 | 2f025967 | Priya | if(end_time.toSec() + MAX_WAIT_TIME < time) //TODO: use another function |
105 | 76cefba1 | Priya | { |
106 | 2f025967 | Priya | best = ℴ |
107 | 5d0687a9 | Priya | best_index = i; |
108 | 2f025967 | Priya | time = end_time.toSec() + MAX_WAIT_TIME; |
109 | 76cefba1 | Priya | } |
110 | } |
||
111 | 5d0687a9 | Priya | |
112 | Order ret; |
||
113 | ret = unassignedOrders->remove(best_index); |
||
114 | assignedOrders.push_back(ret); |
||
115 | return ret;
|
||
116 | 97b6298e | unknown | } |
117 | |||
118 | 3f72678f | Priya | void Scheduler::msg_callback(const std_msgs::String::ConstPtr& msg) |
119 | { |
||
120 | if(msg->data.compare(0, 6, "FAILED") == 0) |
||
121 | { |
||
122 | int order_id = atoi(msg->data.substr(7).c_str()); |
||
123 | 7ac5e9bc | Priya | for(unsigned int i=0; i<assignedOrders.size(); i++) |
124 | 3f72678f | Priya | { |
125 | 7ac5e9bc | Priya | if(assignedOrders[i].getid() == order_id)
|
126 | 3f72678f | Priya | { |
127 | task_failed(assignedOrders[i]); |
||
128 | break;
|
||
129 | } |
||
130 | } |
||
131 | } |
||
132 | else if(msg->data.compare(0, 7, "SUCCESS") == 0) |
||
133 | { |
||
134 | int order_id = atoi(msg->data.substr(8).c_str()); |
||
135 | 7ac5e9bc | Priya | for(unsigned int i=0; i<assignedOrders.size(); i++) |
136 | 3f72678f | Priya | { |
137 | 7ac5e9bc | Priya | if(assignedOrders[i].getid() == order_id)
|
138 | 3f72678f | Priya | { |
139 | task_complete(assignedOrders[i]); |
||
140 | break;
|
||
141 | } |
||
142 | } |
||
143 | } |
||
144 | else if(msg->data.compare(0, 8, "GET_TASK") == 0) |
||
145 | { |
||
146 | 5d0687a9 | Priya | ROS_INFO("SCHEDULER: got get task message");
|
147 | 3f72678f | Priya | int robot = atoi(msg->data.substr(9).c_str()); |
148 | get_task(robot); |
||
149 | } |
||
150 | else if(msg->data.compare(0, 8, "REGISTER") == 0) |
||
151 | { |
||
152 | 7ac5e9bc | Priya | string robot_name = msg->data.substr(9); |
153 | for(unsigned int i=0; i<robots.size(); i++) |
||
154 | { |
||
155 | ad5b5826 | Priya | if(robots[i].name.compare(robot_name) == 0) |
156 | { |
||
157 | 7ac5e9bc | Priya | return;
|
158 | b2876335 | roboclub | } |
159 | 7ac5e9bc | Priya | } |
160 | |||
161 | 3f72678f | Priya | int id = robots.size() +1; |
162 | Robot new_robot; |
||
163 | 7ac5e9bc | Priya | new_robot.name = robot_name; |
164 | new_robot.topic = node.advertise<std_msgs::String>(new_robot.name + "_topic", 1000); |
||
165 | ad5b5826 | Priya | new_robot.sched_status = NEW_ROBOT; |
166 | 3f72678f | Priya | robots.push_back(new_robot); |
167 | |||
168 | std_msgs::String msg; |
||
169 | std::stringstream ss; |
||
170 | 7ac5e9bc | Priya | ss<<"REG_SUCCESS "<<id;
|
171 | 3f72678f | Priya | msg.data = ss.str(); |
172 | 7ac5e9bc | Priya | new_robot.topic.publish(msg); |
173 | 5d0687a9 | Priya | spinOnce(); |
174 | ad5b5826 | Priya | |
175 | 7ac5e9bc | Priya | ROS_INFO("Registration a success");
|
176 | ad5b5826 | Priya | |
177 | assert(robots.size() > 0);
|
||
178 | 3f72678f | Priya | } |
179 | else
|
||
180 | { |
||
181 | 7ac5e9bc | Priya | ROS_INFO("I got a bad message: %s", msg->data.c_str());
|
182 | 3f72678f | Priya | } |
183 | |||
184 | return;
|
||
185 | } |
||
186 | |||
187 | 97b6298e | unknown | /** @Brief: Continuously checks for waiting robots. If no robots are waiting,
|
188 | this function calls the waiting_dance() function. */
|
||
189 | void Scheduler::run()
|
||
190 | { |
||
191 | ad5b5826 | Priya | robot_to_sched = node.subscribe("robot_to_sched", 1000, &Scheduler::msg_callback, this); |
192 | 7ac5e9bc | Priya | ROS_INFO("I am a scheduler!. Now waiting for robots");
|
193 | ad5b5826 | Priya | while(robots.size() < 1 && ok()) |
194 | { |
||
195 | 7ac5e9bc | Priya | spinOnce(); |
196 | ad5b5826 | Priya | } |
197 | ROS_INFO("SCHEDULER: main loop");
|
||
198 | 97b6298e | unknown | while (ok())
|
199 | { |
||
200 | 3f72678f | Priya | ROS_INFO("Scheduler running");
|
201 | 7ac5e9bc | Priya | spinOnce(); |
202 | 5d0687a9 | Priya | while((waitingRobots.empty() || unassignedOrders->arraySize()==0) && ok()) |
203 | { |
||
204 | 76cefba1 | Priya | waiting_dance(); |
205 | 5d0687a9 | Priya | spinOnce(); |
206 | } |
||
207 | ad5b5826 | Priya | |
208 | ROS_INFO("SCHEDULER: Setting task");
|
||
209 | 3f72678f | Priya | Order next = get_next_item(); |
210 | 7ac5e9bc | Priya | Robot r = waitingRobots.front(); |
211 | |||
212 | ad5b5826 | Priya | ROS_INFO("SCHEDULER: Setting task %d to robot %s", next.getid(), r.name.c_str());
|
213 | 3f72678f | Priya | std_msgs::String msg; |
214 | std::stringstream ss; |
||
215 | 7ac5e9bc | Priya | ss<<"SET_TASK "<<next.getid()<<" "<<next.get_source()<<" "<<next.get_dest(); |
216 | 351f71d1 | Priya | std::cout<<"msg: "<<ss.str()<<endl;
|
217 | 3f72678f | Priya | msg.data = ss.str(); |
218 | 7ac5e9bc | Priya | r.topic.publish(msg); |
219 | 5d0687a9 | Priya | |
220 | spinOnce(); |
||
221 | 3f72678f | Priya | |
222 | ad5b5826 | Priya | waitingRobots.front().sched_status = ORDERED_ROBOT; |
223 | 97b6298e | unknown | waitingRobots.pop(); |
224 | } |
||
225 | } |
||
226 | |||
227 | |||
228 |