Bratmobile
task.h
1 #ifndef TASK_H
2 #define TASK_H
3 #include "measurement.h"
4 
5 //if body has sensor, return the corresponding fixture
6 b2Fixture * GetSensor(b2Body * body);
7 
8 //from the bodies in the world, get the disturbance Di for a Task
9 b2Body * GetDisturbance(b2World *);
10 
11 //returns true
12 bool overlaps(b2Body *, Disturbance *);
13 
14 bool overlaps(const b2PolygonShape&, Disturbance *, const b2Transform& robot_pose=b2Transform_zero);
15 
16 //deletes all bodies in the box2d world
17 void world_cleanup(b2World & _world);
18 
19 class Task{
20  friend class Configurator;
21  protected:
22  char planFile[250]; //for debug
23  bool debug_k=false; //delete this it's for debugging on the bhenchod pi
24  bool change =0;
25  b2Transform start=b2Transform_zero;
26  EndCriteria endCriteria; //end criteria other than task encounters a disturbance
27  Direction direction= DEFAULT;
28  int motorStep=0;
29  AffordanceIndex affordance=NONE;
30 
31 
32 public:
33 struct Action{
34 private:
35  float linearSpeed=WHEEL_SPEED_DEFAULT*2; //used to calculate instantaneous velocity using omega
36  float omega=0; //initial angular velocity is 0
37  bool valid=0;
38  float R=WHEEL_SPEED_DEFAULT;
39  float L=WHEEL_SPEED_DEFAULT;
40 
41  public:
42 
43 
44  Action()=default;
45 
46  void init(Direction& direction){
47  switch (direction){
48  case Direction::DEFAULT:
49  L=WHEEL_SPEED_DEFAULT;
50  R=WHEEL_SPEED_DEFAULT;
51  break;
52  case Direction::LEFT:
53  L=-WHEEL_SPEED_TURN;
54  R=WHEEL_SPEED_TURN;
55  break;
56  case Direction::RIGHT:
57  L=WHEEL_SPEED_TURN;//0.2537;
58  R=-WHEEL_SPEED_TURN;
59  break;
60  default:
61  direction=DEFAULT;
62  L=0;
63  R=0;
64  break;
65  }
66  setVelocities(L, R);
67  }
68 
69 void setVelocities(const float & l,const float &r){
70  omega = (MAX_SPEED*(r-l)/BETWEEN_WHEELS); //instant velocity, determines angle increment in willcollide
71  // recordedOmega = omega;
72  linearSpeed = MAX_SPEED*(l+r)/2;
73  //recordedSpeed=linearSpeed;
74  valid=1;
75 }
76 
77  b2Vec2 getLinearVelocity(const float &dt=1)const{ //dt integrates
78  b2Vec2 velocity;
79  velocity.x = linearSpeed *cos(omega)*dt;
80  velocity.y = linearSpeed *sin(omega)*dt;
81  return velocity;
82  }
83 
84  b2Transform getTransform(const float &dt=1)const{ //dt integrates
85  return b2Transform(getLinearVelocity(dt), b2Rot(getOmega(dt)));
86 }
87 
88  float getRWheelSpeed()const{
89  return R;
90  }
91 
92  float getLWheelSpeed()const{
93  return L;
94  }
95 
96  void setRWheelSpeed(float f){
97  R=f;
98  }
99 
100  void setLWheelSpeed(float f){
101  L=f;
102  }
103 
104  bool isValid(){
105  return valid;
106  }
107 
108  float getLinearSpeed(){
109  return linearSpeed;
110  }
111 
112  float getOmega(const float &dt=1)const{
113  return omega*dt;
114  }
115 
122  float getOmega(const float l, const float r, float dt=1)const{
123  float result = (MAX_SPEED*(r-l)/BETWEEN_WHEELS)*TURN_FRICTION*dt;
124  return result;
125  }
126 
127  void setOmega(const float &o){
128  omega =o;
129  }
130 
131  void setLinearSpeed(const float & s){
132  linearSpeed =s;
133  }
134 
135 
136 };
137 
138 
139 
140 class Listener : public b2ContactListener {
141  // int iteration=1;
142  Disturbance * d_ptr;
143  std::vector <b2Body*> collisions;
144  public:
145  Listener(){}
146  Listener(Disturbance * _d): d_ptr(_d){}
147  void BeginContact(b2Contact * contact) {
148  b2Fixture * fixtureA= contact->GetFixtureA();
149  b2Fixture * fixtureB= contact->GetFixtureB();
150  b2BodyUserData bodyData = fixtureA->GetBody()->GetUserData();
151  if (bodyData.pointer==ROBOT_FLAG) { //if fixtureA belongs to robot
152  b2Body * other = contact->GetFixtureB()->GetBody();
153  if (fixtureA->IsSensor()){
154  if (other->GetUserData().pointer==DISTURBANCE_FLAG){
155  d_ptr->validate();
156  }
157  return;
158  }
159  if (fixtureB->IsSensor()){
160  return;
161  }
162  collisions.push_back(other);
163  }
164  bodyData = fixtureB->GetBody()->GetUserData();
165  if (bodyData.pointer==ROBOT_FLAG) {//WAS IF BODYDATA.POINTER if fixtureB belongs to robot
166  b2Body * other = contact->GetFixtureA()->GetBody();
167  if (fixtureB->IsSensor()){
168  if (other->GetUserData().pointer==DISTURBANCE_FLAG){
169  d_ptr->validate();
170  }
171  return;
172  }
173  if (fixtureA->IsSensor()){
174  return;
175  }
176  collisions.push_back(other);
177  }
178  }
179 
180  std::vector <b2Body*> get_collisions(){
181  return collisions;
182  }
183  };
184 
185 Task::Action getAction()const{
186  return action;
187 }
188 
189 AffordanceIndex getAffIndex(){
190  return affordance;
191 }
192 
203 Direction H(Disturbance ob, Direction d, bool topDown=0); //topDown enables Configurator topdown control on reactive behaviour
204 
205 
206 void setEndCriteria(const Angle& angle=SAFE_ANGLE, const Distance& distance=BOX2DRANGE);
207 
208 void setEndCriteria(const Distance& distance);
209 
210 void setEndCriteria(const EndCriteria & ec){
211  endCriteria=ec;
212 }
213 
224 EndedResult checkEnded(b2Transform robotTransform= b2Transform_zero, Direction dir=UNDEFINED, bool relax=0, b2Body* robot=NULL, std::pair<bool,b2Transform> use_start= std::pair <bool,b2Transform>(1, b2Transform_zero));
225 
235 EndedResult checkEnded(const State& n, Direction dir=UNDEFINED, bool relax=false, std::pair<bool,b2Transform> use_start= std::pair <bool,b2Transform>(1, b2Transform_zero)); //usually used to check against control goal
236 
246 bool checkEnded( const b2PolygonShape &box, const b2Transform& robot_pose=b2Transform_zero, Disturbance * dist_obs=NULL );
247 
248 Task(){
249  start = b2Transform(b2Vec2(0.0, 0.0), b2Rot(0));
250  direction = DEFAULT;
251  action.init(direction);
252 }
253 
254 Task(Direction d){
255  direction=d;
256  action.init(direction);
257 }
258 
259 Task(Disturbance ob, Direction d, b2Transform _start=b2Transform(b2Vec2(0.0, 0.0), b2Rot(0.0)), bool topDown=0){
260  start = _start;
261  disturbance = ob;
262  affordance=disturbance.getAffIndex();
263  direction = H(disturbance, d, topDown);
264  action.init(direction);
265  setEndCriteria();
266 }
267 
276 simResult bumping_that(b2World & _world, int iteration, b2Body *, float remaining = SIM_DURATION);
277 
278 EndCriteria getEndCriteria(const Disturbance&);
279 
280 EndCriteria getEndCriteria(){
281  return endCriteria;
282 }
283 
284 bool endCriteria_met(Angle &, Distance &);
285 
286 b2Transform from_Di( const b2Transform * custom_start=NULL, Disturbance * d_obs=NULL); //d_obs disturbance observed rather than D with which task was init
287 
288 void set_change(bool b){
289  change=b;
290 }
291 
292 bool get_change(){
293  return change;
294 }
295 
302 bool is_over(){
303  return change || motorStep==0;
304 }
305 
312  return &disturbance;
313 }
314 
315 const Disturbance & get_disturbance()const{
316  return disturbance;
317 }
318 
319 void setMotorStep(int i){
320  motorStep=i;
321 }
322 
323 int & getMotorStep(){return motorStep;}
324 
325 b2Transform getStart(){
326  return start;
327 }
328 
329 b2Transform& getStartRef(){
330  return start;
331 }
332 
333 Direction get_direction(){
334  return direction;
335 }
336 
337 void set_direction(Direction d){
338  direction=d;
339 }
340 
341 protected:
342  Action action;
343  Disturbance disturbance;
344 
345 
346 };
347 
348 #endif
Definition: measurement.h:44
Definition: configurator.h:17
Definition: measurement.h:52
Definition: task.h:140
Definition: task.h:19
Direction H(Disturbance ob, Direction d, bool topDown=0)
Agent transfer function H which generates a motor output (Action) in response to a disturbance.
Definition: task.cpp:175
EndedResult checkEnded(b2Transform robotTransform=b2Transform_zero, Direction dir=UNDEFINED, bool relax=0, b2Body *robot=NULL, std::pair< bool, b2Transform > use_start=std::pair< bool, b2Transform >(1, b2Transform_zero))
Check if this task has ended based on state information (default are info for the task which calls th...
Definition: task.cpp:240
simResult bumping_that(b2World &_world, int iteration, b2Body *, float remaining=SIM_DURATION)
Executes this task in a Box2D simulation.
Definition: task.cpp:59
Disturbance * get_disturbance_ptr()
Get a pointer to the disturbance.
Definition: task.h:311
bool is_over()
If task has finished executing.
Definition: task.h:302
Definition: disturbance.h:112
Definition: measurement.h:60
Definition: measurement.h:74
Hybrid states in the transition system.
Definition: graphTools.h:69
Definition: task.h:33
float getOmega(const float l, const float r, float dt=1) const
Uses kinematic model to calculate angle.
Definition: task.h:122
Definition: disturbance.h:268