26 #include "Box2D/Box2D.h" 27 #include "constants.h" 31 RobotController::RobotController() {
35 m_controllerParam = controllerParam;
36 m_robotParam = robotParam;
37 m_robotVector.reserve(controllerParam.max_robot_window);
39 printf(
"size of vector %d, \n", m_robotVector.size());
40 m_terrainBody = terrain;
45 m_controllerParam = controllerParam;
46 m_robotParam = robotParam;
47 m_robotVector.reserve(controllerParam.max_robot_window);
49 printf(
"size of vector %d, \n", m_robotVector.size());
50 m_terrainBody = terrain;
54 RobotController::~RobotController() {
57 for (i=0; i<m_robotVector.size(); i++){
60 m_robotVector[i]->m_previousGripJoint =
nullptr;
64 m_robotVector[i]->m_currentGripJoint =
nullptr;
70 m_controllerParam.max_robot_window = nb_robots;
71 m_robotVector.reserve(nb_robots);
80 if (m_robotVector.size() >= m_controllerParam.max_robot_window){
86 m_robotVector.push_back(r);
89 m_robotVector[m_robotVector.size()-1]->createBody(world, m_robotParam, posX, posY, angle);
90 m_robotVector[m_robotVector.size()-1]->setId(m_nbRobots);
91 m_robotVector[m_robotVector.size()-1]->setDelay(delay);
92 m_robotVector[m_robotVector.size()-1]->m_age = m_currentIt;
93 printf(
"Robot created \n");
100 if (pos_id > m_robotVector.size()-1){
101 throw std::string(
"you have only " + std::to_string(m_robotVector.size())
102 +
" active robots, you cannot access robot "+ std::to_string(pos_id));
105 return m_robotVector[pos_id];
111 for (
int i=0; i<m_robotVector.size(); i++){
112 if(m_robotVector[i]->getId()==id){
113 return m_robotVector[i];
121 for (i=0; i<m_robotVector.size(); i++){
122 m_robotVector[i]->drawBody(window, m_to_px);
123 m_robotVector[i]->drawGripJoint(window, m_to_px);
130 b2Body* bodyContactA = contact->GetFixtureA()->GetBody();
131 b2Body* bodyContactB = contact->GetFixtureB()->GetBody();
138 bool contactorA =
false;
139 bool contactorB =
false;
141 if(!(bodyContactA == m_terrainBody)){
143 rA=
static_cast<Robot*
>(bodyContactA->GetUserData());
146 if(!(bodyContactB == m_terrainBody)){
148 rB=
static_cast<Robot*
>(bodyContactB->GetUserData());
152 contactorA = (rA->
isMoving()||rA->m_start)
153 && (rA->contactOnGripSide(contact));
157 contactorB = (rB->
isMoving()||rB->m_start)
158 && (rB->contactOnGripSide(contact));
161 if (robotA && robotB && (rA==rB)){
162 printf(
"contact within robot\n");
167 if (contactorA && contactorB){
169 double angleA = rA->
getBody()->GetAngle() - rA->m_referenceAngle;
171 double angleB = rB->
getBody()->GetAngle() - rB->m_referenceAngle;
173 if(abs(angleA) > m_controllerParam.angle_limit && angleB > m_controllerParam.angle_limit){
174 rA->
gripSide(contact, bodyContactB, m_M_TO_PX);
176 rB->
gripSide(contact, bodyContactA, m_M_TO_PX);
181 else if(abs(angleA) > m_controllerParam.angle_limit){
182 rA->
gripSide(contact, bodyContactB, m_M_TO_PX);
188 else if(abs(angleB) > m_controllerParam.angle_limit){
189 rB->
gripSide(contact, bodyContactA, m_M_TO_PX);
197 else if (contactorB){
199 double angleB = rB->
getBody()->GetAngle() - rB->m_referenceAngle;
200 if(abs(angleB) > m_controllerParam.angle_limit){
202 rB->
gripSide(contact, bodyContactA, m_M_TO_PX);
211 else if (contactorA){
213 double angleA = rA->
getBody()->GetAngle() - rA->m_referenceAngle;
217 if(abs(angleA) > m_controllerParam.angle_limit|| angleA==0){
219 rA->
gripSide(contact, bodyContactB, m_M_TO_PX);
236 if(!(robot.m_start)){
237 robot.
setDelay(
int(m_controllerParam.walk_delay*FPS));
239 robot.m_moving =
false;
256 robot.
setDelay(
int(m_controllerParam.bridge_delay*FPS));
257 robot.m_moving =
false;
260 if (robot.
getId() > m_idLastRobot){
261 m_idLastRobot = robot.
getId();
262 m_stableTime = m_currentIt/FPS;
266 robot.m_bridgeAge = m_currentIt;
268 if(!robot.
getMotor(robot.m_movingSide)){
269 printf(
"Pourquoi putain de nul \n");
299 robot.m_start =
false;
302 side s = robot.m_movingSide;
303 b2World* world = robot.
getBody()->GetWorld();
306 b2PrismaticJointDef gripJointDef= robot.
getJointDef(s);
308 if((&gripJointDef ==
nullptr)){
311 b2PrismaticJoint* gripJoint =
static_cast<b2PrismaticJoint*
>(world->CreateJoint( &gripJointDef ));
318 robot.m_currentGripJoint = gripJoint;
319 robot.m_referenceAngle = robot.
getBody()->GetAngle();
323 printf(
"already a joint \n");
330 robot.m_ready =
true;
344 m_robotVector.push_back(robot);
348 if(!m_robotToDestroy.empty()){
349 printf(
"remove 0 \n");
351 for (
int i=0; i<m_robotToDestroy.size(); i++){
352 int id = m_robotToDestroy[i];
354 std::vector<Robot*>::iterator pRob = m_robotVector.begin()+id;
356 if(!(
id == m_robotVector.size()-1)){
357 printf(
"remove 0b \n");
358 std::swap(m_robotVector[
id], m_robotVector.back());
359 printf(
"remove 0c \n");
362 printf(
"remove 1 \n");
363 m_robotVector.pop_back();
364 printf(
"remove 2 \n");
367 m_robotToDestroy.clear();
372 int pos = (m_robotVector[id]->getBody()->GetWorldCenter()).x * m_M_TO_PX;
374 m_robotToDestroy.push_back(
id);
380 if(robot.m_movingSide == LEFT){
381 robot.m_movingSide = RIGHT;
383 else if(robot.m_movingSide == RIGHT){
384 robot.m_movingSide = LEFT;
404 robot.
setDelay(
int(m_controllerParam.bridge_delay*60));
412 if (m_stableTime > 0){
413 if (m_currentIt/FPS > (m_stableTime + m_controllerParam.stability_condition)){
422 m_isDissolved =
true;
433 return m_dissolutionTime;
438 for (
int i=0; i<m_robotVector.size(); i++){
440 if(m_robotVector[i]->getId()==-1){
441 printf(
"continue for loop \n");
450 if(m_robotVector[i]->isReady()){
452 if(m_robotVector[i]->getState()==BRIDGE){
454 if(m_nbRobInBridge==0){
455 m_dissolutionTime = m_currentIt*FPS;
459 m_robotVector[i]->m_ready=
false;
462 m_robotVector[i]->setState(WALK);
463 m_robotVector[i]->m_bridgeAge = 0;
465 m_robotVector[i]->m_moving=
true;
466 if (m_robotVector[i]->checkGripp(m_robotVector[i]->m_movingSide)){
470 printf(
"\n wrong moving wheel \n");}
471 destroyJoints(*m_robotVector[i], m_robotVector[i]->m_movingSide);
472 m_robotVector[i]->moveBodyWithMotor();
476 if(m_robotVector[i]->isMoving()){
477 if(m_robotVector[i]->getDelay() ==
int(- m_controllerParam.time_before_pushing*FPS)){
480 printf(
"\n Robot moving for too long, it is pushing \n");
496 b2ContactEdge* contactList = r.
getWheel(r.m_movingSide)->GetContactList();
497 b2Contact* contact = contactList->contact;
498 for (
int i=0; i<10; i++){
499 if(contact->IsTouching() &&!(contactList->other == r.
getBody()) && (r.contactOnGripSide(contact))){
500 double angle = abs(r.
getBody()->GetAngle() - r.m_referenceAngle);
501 if(angle > m_angle_min ){
503 if (! (contactList->other==m_terrainBody)){
504 Robot* r_other =
static_cast<Robot*
>( contactList->other->GetUserData() );
505 if(r_other->
getId()>0){
508 r.
gripSide(contact, contactList->other, m_M_TO_PX);
509 r.
setDelay(m_controllerParam.walk_delay);
515 r.
gripSide(contact, contactList->other, m_M_TO_PX);
516 r.
setDelay(m_controllerParam.walk_delay);
521 if(contactList->next ==
nullptr){
525 contactList = contactList->next;
526 contact = contactList->contact;
533 float x=r->
getBody()->GetPosition().x;
534 if(x < (m_robotParam.body_length + posX)){
544 for (
int i=0; i<m_robotVector.size(); i++){
545 if(m_robotVector[i]->getState() == s){
553 return m_robotVector.size();
560 for (
int i=0; i<m_robotVector.size(); i++){
561 if(m_robotVector[i]->getState() == BRIDGE){
562 if(m_robotVector[i]->getPosition().y < h){
563 h=m_robotVector[i]->getPosition().y;
564 id=m_robotVector[i]->getId();
568 for (
int i=0; i<m_robotVector.size(); i++){
569 if(m_robotVector[i]->getState() == WALK){
570 if(m_robotVector[i]->getPosition().y > h && m_robotVector[i]->getId()<id){
bool robotStacking(Robot *r, float posX)
void robotOut(double end_x, int id)
void findContactRobots(b2Contact *contact)
double getDissolutionTime()
int getNbRobots(e_state s)
Robot * getRobotWithId(int id)
void setBridgeStability(bool stable)
bool checkGrabbed(Robot &robot)
void setNbRobots(int nb_robots)
void drawRobots(sf::RenderWindow &window, double m_to_px)
Robot * getRobot(int pos_id)
void addRobot(Robot *robot)
bool createRobot(b2World *world, int delay, double posX, double posY, double angle=0)
b2PrismaticJointDef getJointDef(side s)
void wait_delay(Robot &robot)
b2Body * getWheel(side s)
void limitMotorRotation(side s, double limit_angle_rad)
void resetNbJoint(side s)
void incrementNbJoint(side s)
void setContact(bool contact)
b2RevoluteJoint * getMotor(side s)
void setRobotState(Robot &robot, e_state robotState)
bool gripSide(b2Contact *contact, b2Body *otherBody, double m_to_px)
void destroyJoints(Robot &robot, side s)
void invertMovingWheel(Robot &robot)
Implement the RobotController class. This class act as a supervisor for the Robots.
void setScale(double m_to_px)
double getStabilizationTime()
void setState(e_state state)
b2PrismaticJoint * m_previousGripJoint
bool robotPushing(Robot &r)
void createGripRobots(Robot &robot)