Bratmobile
task.h
1 #ifndef TASK_H
2 #define TASK_H
3 #include "measurement.h"
4 #pragma once
5 extern const bool DEBUG;
6 
10 b2Fixture * GetSensor(b2Body * body);
11 
16 b2Body * GetDisturbance(b2World * x);
17 
25 bool overlaps(b2Body * robot, const Disturbance *const);
26 
35 bool overlaps(const b2PolygonShape& box, const Disturbance * const d, const b2Transform& robot_pose=b2Transform_zero);
36 
41 void world_cleanup(b2World & _world);
42 
47 class Task{
48  friend class Configurator;
49  protected:
50  char planFile[250]; //for debug
51  char collisionFile[50];//debug
52  // bool debug_k=false; //delete this it's for debugging on the bhenchod pi
53  bool change =0;
54  b2Transform start=b2Transform_zero;
55  EndCriteria endCriteria; //end criteria other than task encounters a disturbance
56  Direction direction= DEFAULT;
57  int motorStep=0;
58  AffordanceIndex affordance=NONE;
59 
60 
61 public:
66 struct Action{
67 private:
68  float linearSpeed=WHEEL_SPEED_DEFAULT*2; //used to calculate instantaneous velocity using omega
69  float omega=0; //initial angular velocity is 0
70  bool valid=0;
71  float R=WHEEL_SPEED_DEFAULT;
72  float L=WHEEL_SPEED_DEFAULT;
73 
74  public:
75 
76 
77  Action()=default;
78 
79  void init(Direction& direction){
80  switch (direction){
81  case Direction::DEFAULT:
82  L=WHEEL_SPEED_DEFAULT;
83  R=WHEEL_SPEED_DEFAULT;
84  break;
85  case Direction::LEFT:
86  L=-WHEEL_SPEED_TURN;
87  R=WHEEL_SPEED_TURN;
88  break;
89  case Direction::RIGHT:
90  L=WHEEL_SPEED_TURN;//0.2537;
91  R=-WHEEL_SPEED_TURN;
92  break;
93  default:
94  direction=DEFAULT;
95  L=0;
96  R=0;
97  break;
98  }
99  setVelocities(L, R);
100  }
101 
102 void setVelocities(const float & l,const float &r){
103  omega = (MAX_SPEED*(r-l)/BETWEEN_WHEELS); //instant velocity, determines angle increment in willcollide
104  linearSpeed = MAX_SPEED*(l+r)/2;
105  valid=1;
106 }
107 
108  b2Vec2 getLinearVelocity(const float &dt=1)const{ //dt integrates
109  b2Vec2 velocity;
110  velocity.x = linearSpeed *cos(omega)*dt;
111  velocity.y = linearSpeed *sin(omega)*dt;
112  return velocity;
113  }
114 
120  b2Transform getTransform(const float &dt=1)const{ //dt integrates
121  return b2Transform(getLinearVelocity(dt), b2Rot(getOmega(dt)));
122 }
123 
124  float getRWheelSpeed()const{
125  return R;
126  }
127 
128  float getLWheelSpeed()const{
129  return L;
130  }
131 
132  void setRWheelSpeed(float f){
133  R=f;
134  }
135 
136  void setLWheelSpeed(float f){
137  L=f;
138  }
139 
140  bool isValid(){
141  return valid;
142  }
143 
144  float getLinearSpeed(){
145  return linearSpeed;
146  }
147 
148  float getOmega(const float &dt=1)const{
149  return omega*dt;
150  }
151 
158  float getOmega(const float l, const float r, float dt=1)const{
159  float result = (MAX_SPEED*(r-l)/BETWEEN_WHEELS)*TURN_FRICTION*dt;
160  return result;
161  }
162 
163  void setOmega(const float &o){
164  omega =o;
165  }
166 
167  void setLinearSpeed(const float & s){
168  linearSpeed =s;
169  }
170 
171 
172 };
173 
174 protected:
179 class Listener : public b2ContactListener {
180  Disturbance * d_ptr;
181  std::vector <b2Body*> collisions;
182  public:
183  Listener(){}
184  Listener(Disturbance * _d): d_ptr(_d){}
185  void BeginContact(b2Contact * contact) {
186  b2Fixture * fixtureA= contact->GetFixtureA();
187  b2Fixture * fixtureB= contact->GetFixtureB();
188  b2BodyUserData bodyData = fixtureA->GetBody()->GetUserData();
189  if (bodyData.pointer==ROBOT_FLAG) { //if fixtureA belongs to robot
190  b2Body * other = contact->GetFixtureB()->GetBody();
191  if (fixtureA->IsSensor()){
192  if (other->GetUserData().pointer==DISTURBANCE_FLAG){
193  d_ptr->validate();
194  }
195  return;
196  }
197  if (fixtureB->IsSensor()){
198  return;
199  }
200  collisions.push_back(other);
201  }
202  bodyData = fixtureB->GetBody()->GetUserData();
203  if (bodyData.pointer==ROBOT_FLAG) {//WAS IF BODYDATA.POINTER if fixtureB belongs to robot
204  b2Body * other = contact->GetFixtureA()->GetBody();
205  if (fixtureB->IsSensor()){
206  if (other->GetUserData().pointer==DISTURBANCE_FLAG){
207  d_ptr->validate();
208  }
209  return;
210  }
211  if (fixtureA->IsSensor()){
212  return;
213  }
214  collisions.push_back(other);
215  }
216  }
217 
218  std::vector <b2Body*> get_collisions(){
219  return collisions;
220  }
221  };
222 
223 public:
224 Task::Action getAction()const{
225  return action;
226 }
227 
228 AffordanceIndex getAffIndex(){
229  return affordance;
230 }
231 
242 Direction H(Disturbance ob, Direction d, bool topDown=0); //topDown enables Configurator topdown control on reactive behaviour
243 
244 
252 void setEndCriteria(const Angle& angle=SAFE_ANGLE, const Distance& distance=BOX2DRANGE);
253 
254 void setEndCriteria(const Distance& distance);
255 
256 void setEndCriteria(const EndCriteria & ec){
257  endCriteria=ec;
258 }
259 
260 // void adjustEndCriteria(b2Transform t){endCriteria.adjust(t);}
261 
272 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));
273 
283 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
284 
294 bool checkEnded(const b2PolygonShape &box, const b2Transform& robot_pose=b2Transform_zero, Disturbance * dist_obs=NULL );
295 
296 Task(){
297  start = b2Transform(b2Vec2(0.0, 0.0), b2Rot(0));
298  direction = DEFAULT;
299  action.init(direction);
300 }
301 
302 Task(Direction d){
303  direction=d;
304  action.init(direction);
305 }
306 
307 Task(Disturbance ob, Direction d, b2Transform _start=b2Transform(b2Vec2(0.0, 0.0), b2Rot(0.0)), bool topDown=0){
308  start = _start;
309  disturbance = ob;
310  affordance=disturbance.getAffIndex();
311  direction = H(disturbance, d, topDown);
312  action.init(direction);
313  setEndCriteria();
314 }
315 
324 simResult bumping_that(b2World & _world, int iteration, b2Body *, float remaining = SIM_DURATION);
325 
330 
335  return endCriteria;
336 }
337 
344 bool endCriteria_met(Angle & a, Distance &d);
345 
353 b2Transform from_Di( const b2Transform * custom_start=NULL, Disturbance * d_obs=NULL); //d_obs disturbance observed rather than D with which task was init
354 
355 void set_change(bool b){
356  change=b;
357 }
358 
359 bool get_change(){
360  return change;
361 }
362 
369 bool is_over(){
370  return change || motorStep==0;
371 }
372 
379  return &disturbance;
380 }
381 
382 const Disturbance & get_disturbance()const{
383  return disturbance;
384 }
385 
386 void setMotorStep(int i){
387  motorStep=i;
388 }
389 
390 int getMotorStep()const{return motorStep;}
391 
392 b2Transform getStart(){
393  return start;
394 }
395 
396 b2Transform& getStartRef(){
397  return start;
398 }
399 
400 Direction get_direction(){
401  return direction;
402 }
403 
404 void set_direction(Direction d){
405  direction=d;
406 }
407 
408 protected:
409  Action action;
410  Disturbance disturbance;
411 
412 bool isTurnFinished(const b2Transform & robotTransform, Direction dir);
413 
414 bool isMoving();
415 
416 };
417 
418 #endif
Definition: measurement.h:71
Definition: configurator.h:17
Definition: measurement.h:80
Used to find collisions in the Box2D simulation.
Definition: task.h:179
A closed hybrid control loop. It has an initial disturbance representing the continuous state and a d...
Definition: task.h:47
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:178
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
bool endCriteria_met(Angle &a, Distance &d)
Returns true if the endCriteria is met based on.
Definition: task.cpp:394
void setEndCriteria(const Angle &angle=SAFE_ANGLE, const Distance &distance=BOX2DRANGE)
Sets the end criteria for this task (bounds of the Flow condition). Angle is a valid measurement for ...
Definition: task.cpp:211
simResult bumping_that(b2World &_world, int iteration, b2Body *, float remaining=SIM_DURATION)
Executes this task in a Box2D simulation.
Definition: task.cpp:58
b2Transform from_Di(const b2Transform *custom_start=NULL, Disturbance *d_obs=NULL)
Returns a b2Transform expressing the pose of the disturbance relative to the robot in the robot's loc...
Definition: task.cpp:361
Disturbance * get_disturbance_ptr()
Get a pointer to the disturbance.
Definition: task.h:378
EndCriteria & getEndCriteria()
Returns a REFERENCE to the endCriteria.
Definition: task.h:334
bool is_over()
If task has finished executing.
Definition: task.h:369
Definition: disturbance.h:113
Defines the end criteria for a Task, i.e. when it is considered to be finished.
Definition: measurement.h:92
Provides information on whether a Task has ended and with what heuristic -estimated- cost (chi) and p...
Definition: measurement.h:126
Hybrid states in the transition system.
Definition: graphTools.h:69
The motor instructions generated by the control strategy used in this tasks.
Definition: task.h:66
float getOmega(const float l, const float r, float dt=1) const
Uses kinematic model to calculate angle.
Definition: task.h:158
b2Transform getTransform(const float &dt=1) const
Gets the ROBOT's displacement in the world frame after dt seconds.
Definition: task.h:120
Definition: disturbance.h:269