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