Project

General

Profile

Statistics
| Branch: | Revision:

root / scout / libscout / src / behaviors / Scheduler.cpp @ 5755691e

History | View | Annotate | Download (5.49 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
  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
}
36

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

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

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

    
82
/** @Brief: Do a waiting dance. */
83
void Scheduler::waiting_dance()
84
{ 
85
    //ROS_INFO("Scheduler: TEEHEE i do a dance!");
86
}
87

    
88
/** @Brief: The scheduling algorithm. Picks a task and pops from the PQWrapper. */
89
Order Scheduler::get_next_item()
90
{
91
  Time t = ros::TIME_MAX; 
92
  double time = t.toSec();
93

    
94
  Order* best;
95
  int best_index;
96
  for(unsigned int i=0; i<unassignedOrders->arraySize(); i++)
97
  {
98
    Order order = unassignedOrders->peek(i);
99

    
100
    Time end_time = order.get_start_time() - order.get_est_time();
101

    
102
    if(end_time.toSec() + MAX_WAIT_TIME < time) //TODO: use another function
103
    {
104
      best = &order;
105
      best_index = i;
106
      time = end_time.toSec() + MAX_WAIT_TIME;
107
    }
108
  }
109

    
110
  Order ret;
111
  ret = unassignedOrders->remove(best_index);
112
  assignedOrders.push_back(ret);
113
  return ret;
114
}
115

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

    
159
    int id = robots.size() +1;
160
    Robot new_robot;
161
    new_robot.name = robot_name;
162
    new_robot.topic = node.advertise<std_msgs::String>(new_robot.name + "_topic", 1000);
163
    new_robot.sched_status = NEW_ROBOT;
164
    robots.push_back(new_robot);
165

    
166
    std_msgs::String msg;
167
    std::stringstream ss;
168
    ss<<"REG_SUCCESS "<<id;
169
    msg.data = ss.str();
170
    new_robot.topic.publish(msg);
171
    spinOnce();
172

    
173
    ROS_INFO("Registration a success");
174

    
175
    assert(robots.size() > 0);
176
  }
177
  else
178
  {
179
    ROS_INFO("I got a bad message: %s", msg->data.c_str());
180
  }
181

    
182
  return;
183
}
184

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

    
210
    ROS_INFO("SCHEDULER: Setting task %d to robot %s", next.getid(), r.name.c_str());
211
    std_msgs::String msg;
212
    std::stringstream ss;
213
    ss<<"SET_TASK "<<next.getid()<<" "<<next.get_source()<<" "<<next.get_dest();
214
    std::cout<<"msg: "<<ss.str()<<endl;
215
    msg.data = ss.str();
216
    r.topic.publish(msg);
217
  
218
    spinOnce();
219

    
220
    waitingRobots.front().sched_status = ORDERED_ROBOT;
221
                waitingRobots.pop();
222
        }
223
}
224

    
225

    
226

    
227