Project

General

Profile

Statistics
| Branch: | Revision:

root / scout / libscout / src / behaviors / Scheduler.cpp @ 5d0687a9

History | View | Annotate | Download (5.82 KB)

1
#include "Scheduler.h"
2
#include "../helper_classes/Order.h"
3

    
4
using namespace std;
5

    
6
/** @Brief: Initialize data structures for the scheduler. */
7
Scheduler::Scheduler(std::string scoutname):Behavior(scoutname, "Scheduler")
8
{
9
  unassignedOrders = new PQWrapper(NUM_TASKS);
10

    
11
        create_orders();
12
}
13

    
14
/** @Brief: Free allocatetd memory. */
15
Scheduler::~Scheduler()
16
{
17
  delete unassignedOrders;
18
}
19

    
20
/** @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
void Scheduler::get_task(int robot)
28
{
29
  ROS_INFO("SCHEDULER: robots vector size is: %d", robots.size());
30
  Robot my_robot = robots[robot-1];
31
  ROS_INFO("SCHEDULER: My robot is %s", my_robot.name.c_str());
32
  if(my_robot.sched_status != WAITING_ROBOT)
33
  {
34
          waitingRobots.push(my_robot);
35
    my_robot.sched_status = WAITING_ROBOT;
36
    ROS_INFO("SCHEDULER: Added to scheduler %d", my_robot.sched_status);
37
  }
38
}
39

    
40
/** @Brief: Statically add orders to the Priority Queue Wrapper.*/
41
void Scheduler::create_orders()
42
{
43
  Path p;
44
  p.len = 0;
45
  p.path = NULL;
46
  Time t = ros::Time::now();
47
  Duration end(0);
48
  Duration five(5);
49
  Duration three(3);
50
  Duration ten(10);
51
        Order a(1,0,1,t+ten,p,end);
52
  Order b(2,0,1,t+five,p,end);
53
  Order c(3,0,9,t+three,p,end);
54
  Order d(4,0,2,t,p,end);
55
  Order e(5,0,4,t,p,end);
56
        
57
        unassignedOrders->insert(a);
58
        unassignedOrders->insert(b);
59
        unassignedOrders->insert(c);
60
        unassignedOrders->insert(d);
61
        unassignedOrders->insert(e);
62
}
63

    
64
/** @Brief: This is a confirmation that the task is complete. 
65
    This function removes the order from assignedOrders. */
66
void Scheduler::task_complete(Order o)
67
{
68
  ROS_INFO("Scheduler: Task id %d was completed", o.getid());
69
  for (unsigned int i=0; i<assignedOrders.size(); i++)
70
  {
71
    if (assignedOrders[i].getid()==o.getid())
72
    {
73
      assignedOrders.erase(assignedOrders.begin()+i);
74
    }
75
  }
76
}
77

    
78
/** @Brief: This is a confirmation that the task failed. 
79
    This function places the order back on the PQWrapper. */
80
void Scheduler::task_failed(Order o)
81
{
82
  ROS_INFO("Scheduler: Task id %d was failed", o.getid());
83
        task_complete(o);
84
        unassignedOrders->insert(o);
85
}
86

    
87
/** @Brief: Do a waiting dance. */
88
void Scheduler::waiting_dance()
89
{ 
90
    //ROS_INFO("Scheduler: TEEHEE i do a dance!");
91
}
92

    
93
/** @Brief: The scheduling algorithm. Picks a task and pops from the PQWrapper. */
94
Order Scheduler::get_next_item()
95
{
96
  Time t = ros::TIME_MAX; 
97
  double time = t.toSec();
98

    
99
  Order* best;
100
  int best_index;
101
  for(unsigned int i=0; i<unassignedOrders->arraySize(); i++)
102
  {
103
    Order order = unassignedOrders->peek(i);
104

    
105
    Time end_time = order.get_start_time() - order.get_est_time();
106

    
107
    if(end_time.toSec() + MAX_WAIT_TIME < time) //TODO: use another function
108
    {
109
      best = &order;
110
      best_index = i;
111
      time = end_time.toSec() + MAX_WAIT_TIME;
112
    }
113
  }
114

    
115
  Order ret;
116
  ret = unassignedOrders->remove(best_index);
117
  assignedOrders.push_back(ret);
118
  return ret;
119
}
120

    
121
void Scheduler::msg_callback(const std_msgs::String::ConstPtr& msg)
122
{
123
  if(msg->data.compare(0, 6, "FAILED") == 0)
124
  {
125
    int order_id = atoi(msg->data.substr(7).c_str());
126
    for(unsigned int i=0; i<assignedOrders.size(); i++)
127
    {
128
      if(assignedOrders[i].getid() == order_id)
129
      {
130
        task_failed(assignedOrders[i]);
131
        break;
132
      }
133
    }
134
  }
135
  else if(msg->data.compare(0, 7, "SUCCESS") == 0)
136
  {
137
    int order_id = atoi(msg->data.substr(8).c_str());
138
    for(unsigned int i=0; i<assignedOrders.size(); i++)
139
    {
140
      if(assignedOrders[i].getid() == order_id)
141
      {
142
        task_complete(assignedOrders[i]);
143
        break;
144
      }
145
    }
146
  }
147
  else if(msg->data.compare(0, 8, "GET_TASK") == 0)
148
  {
149
    ROS_INFO("SCHEDULER: got get task message");
150
    int robot = atoi(msg->data.substr(9).c_str());
151
    get_task(robot);
152
  }
153
  else if(msg->data.compare(0, 8, "REGISTER") == 0)
154
  {
155
    string robot_name = msg->data.substr(9);
156
    for(unsigned int i=0; i<robots.size(); i++)
157
    {
158
      if(robots[i].name.compare(robot_name) == 0)
159
      { 
160
        return;
161
      }
162
    }
163

    
164
    int id = robots.size() +1;
165
    Robot new_robot;
166
    new_robot.name = robot_name;
167
    new_robot.topic = node.advertise<std_msgs::String>(new_robot.name + "_topic", 1000);
168
    new_robot.sched_status = NEW_ROBOT;
169
    robots.push_back(new_robot);
170

    
171
    ROS_INFO("Registration a robot %s %d", new_robot.name.c_str(), robots.size());
172
    std_msgs::String msg;
173
    std::stringstream ss;
174
    ss<<"REG_SUCCESS "<<id;
175
    msg.data = ss.str();
176
    new_robot.topic.publish(msg);
177
    spinOnce();
178

    
179
    ROS_INFO("Registration a success");
180

    
181
    assert(robots.size() > 0);
182
  }
183
  else
184
  {
185
    ROS_INFO("I got a bad message: %s", msg->data.c_str());
186
  }
187

    
188
  return;
189
}
190

    
191
/** @Brief: Continuously checks for waiting robots. If no robots are waiting,
192
    this function calls the waiting_dance() function. */
193
void Scheduler::run()
194
{
195
  robot_to_sched = node.subscribe("robot_to_sched", 1000, &Scheduler::msg_callback, this);
196
  ROS_INFO("I am a scheduler!. Now waiting for robots");
197
  while(robots.size() < 1 && ok())
198
  {
199
    ROS_INFO("Robots size: %d", robots.size());
200
    spinOnce();
201
  }
202
  ROS_INFO("SCHEDULER: main loop");
203
        while (ok())
204
        {
205
    ROS_INFO("Scheduler running");
206
    spinOnce();
207
                while((waitingRobots.empty() || unassignedOrders->arraySize()==0) && ok())
208
    {
209
      waiting_dance();
210
      spinOnce();
211
    }
212
  
213
    ROS_INFO("SCHEDULER: Setting task");
214
    Order next = get_next_item();
215
    Robot r = waitingRobots.front();
216

    
217
    ROS_INFO("SCHEDULER: Setting task %d to robot %s", next.getid(), r.name.c_str());
218
    std_msgs::String msg;
219
    std::stringstream ss;
220
    ss<<"SET_TASK "<<next.getid()<<" "<<next.get_source()<<" "<<next.get_dest();
221
    msg.data = ss.str();
222
    r.topic.publish(msg);
223
  
224
    spinOnce();
225

    
226
    waitingRobots.front().sched_status = ORDERED_ROBOT;
227
                waitingRobots.pop();
228
        }
229
}
230

    
231

    
232

    
233