36 bool distance_from_bottom =
false;
38 bool gaussian_delay =
true;
39 bool periodic_delay =
false;
47 window.create(sf::VideoMode(m_config.window.WINDOW_X_PX, m_config.window.WINDOW_Y_PX, 32),
"Ant bridge simulation");
48 window.setFramerateLimit(FPS);
49 world->SetGravity(b2Vec2(0,m_config.simulation.gravity));
51 m_terrain.
create(m_world, window, m_config.terrain, m_config.window.WINDOW_X_PX, m_config.robot.body_length );
57 if(distance_from_bottom){
59 m_config.simulation.robot_initial_posX = m_terrain.
getTopLeftCorner().x + V_slope - m_config.simulation.robot_initial_posX*m_config.robot.body_length;
61 else if(!(m_terrain.
getType()==DEFAULT)){
62 m_config.simulation.robot_initial_posX = m_terrain.
getTopLeftCorner().x - m_config.simulation.robot_initial_posX*m_config.robot.body_length;
66 m_config.robot.wheel_radius = (m_config.robot.body_length - 0.02)/4;
67 m_config.simulation.robot_initial_posY = m_terrain.
getTopLeftCorner().y - m_config.robot.wheel_radius;
69 m_robotController.create(m_config.controller, m_config.robot, m_terrain.
getBody());
74 m_gauss_delay = std::normal_distribution<double>(m_config.simulation.robot_delay,m_std_dev);
87 m_world->SetContactListener(myContactListener);
88 window.setFramerateLimit(60);
94 Both cases are then almost identical apart from the simulation part.
98 if(m_config.simulation.visualization){
100 while (window.isOpen())
104 while (window.pollEvent(event))
107 if (event.type == sf::Event::Closed)
111 if (event.key.code == sf::Keyboard::S)
113 sf::Image Screen = window.capture();
114 std::string name =
"screenshot_" + std::to_string(m_elapsedTime) +
".jpg";
115 Screen.saveToFile(name);
121 if(m_elapsedTime < m_config.simulation.bridge_duration && !m_stacking){
126 printf(
"robot stacking \n");
130 m_robotController.
step(window.getSize().x);
131 m_world->Step(1.f/60.f, 100, 100);
135 window.clear(sf::Color::White);
137 m_robotController.
drawRobots(window, m_to_px);
143 if(m_currentIt % 600 == 0){
147 m_elapsedTime += 1.f/FPS;
153 m_config.simulation.robot_delay = 2.5/(cos(PI/(18*60)*m_currentIt)*cos(PI/(18*60)*m_currentIt));
158 else if(m_elapsedTime < m_config.simulation.dissolution_duration + m_config.simulation.bridge_duration){
160 m_robotController.
step(window.getSize().x);
161 m_world->Step(1.f/60.f, 100, 100);
165 window.clear(sf::Color::White);
167 m_robotController.
drawRobots(window, m_to_px);
173 if(m_currentIt % 600 == 0){
177 m_elapsedTime += 1.f/FPS;
191 while (m_elapsedTime < m_config.simulation.bridge_duration )
196 printf(
"robot stacking \n");
201 m_robotController.
step(window.getSize().x);
202 m_world->Step(1.f/60.f, 100, 100);
208 if(m_currentIt % 600 == 0){
212 m_elapsedTime += 1.f/FPS;
218 m_config.simulation.robot_delay = 2.5/(cos(PI/(18*60)*m_currentIt)*cos(PI/(18*60)*m_currentIt));
223 m_nbRobotsInBridgeState = m_robotController.
getNbRobots(BRIDGE);
224 m_nbRobotsInBridge = m_nbRobotsInBridgeState + m_robotController.
getNbRobotsBlocked();
225 m_elapsedTimeBridge = m_elapsedTime;
230 while (m_elapsedTime < m_config.simulation.dissolution_duration + m_config.simulation.bridge_duration)
233 m_robotController.
step(window.getSize().x);
234 m_world->Step(1.f/60.f, 100, 100);
241 if(m_currentIt % 600 == 0){
245 m_elapsedTime += 1.f/FPS;
250 printf(
"end loop \n");
251 m_bridgeFile.close();
263 if(m_nbRobots < m_config.simulation.nb_robots){
264 int final_it = int(60 * m_config.simulation.robot_delay) ;
267 if(m_nbRobots && m_robotController.
robotStacking(m_robotController.
getRobotWithId(m_nbRobots), m_config.simulation.robot_initial_posX)){
271 m_robotController.
createRobot(m_world, 0, m_config.simulation.robot_initial_posX, m_config.simulation.robot_initial_posY);
274 m_config.simulation.robot_delay=std::max(m_gauss_delay(m_gen), 1.5);
275 std::cout<<
"delay rand= "<< m_config.simulation.robot_delay<<std::endl;
283 int walk_delay=int(m_config.controller.walk_delay*FPS);
284 if(delay > 0 && delay < walk_delay){
285 m_config.simulation.robot_phase = PI*(1 + float(walk_delay-delay)/float(walk_delay));
288 m_config.simulation.robot_phase = moduloAngle(m_robotController.
getRobot(0)->
getAngle(), PI);
304 int delay = int(m_config.controller.walk_delay*FPS);
305 m_robotController.
createRobot(m_world, delay, m_config.simulation.robot_initial_posX, m_config.simulation.robot_initial_posY);
306 std::cout <<
"first robot created"<<std::endl;
310 else if(m_nbRobots < m_config.simulation.nb_robots){
313 distance -= m_config.simulation.robot_initial_posX*m_config.robot.body_length;
314 float target = m_config.simulation.robot_distance*m_config.robot.body_length;
316 if(m_config.simulation.robot_phase > PI){
317 int delay = round(
int(m_config.controller.walk_delay*FPS)*(2*PI-m_config.simulation.robot_phase)/PI);
320 if(m_robotController.
createRobot(m_world, 0, x, m_config.simulation.robot_initial_posY)){
329 float flipping_distance = m_config.robot.body_length-2*m_config.robot.wheel_radius;
330 distance = distance - flipping_distance*sin(angle)/2;
331 int delay = -round(
int(m_config.controller.walk_delay*FPS)*m_config.simulation.robot_phase/PI);
334 if(m_robotController.
createRobot(m_world, 0, x, m_config.simulation.robot_initial_posY)){
345 return m_robotController;
349 sf::RenderWindow* ptrWind = &window;
355 double x_start = FLT_MAX;
359 for(
int i=0 ; i<n ; i++){
364 if(r->m_currentGripJoint){
365 double x_r = r->m_currentGripJoint->GetAnchorA().x;
368 y_start = r->m_currentGripJoint->GetAnchorA().y;
383 double y_bottom_bridge = m_terrain.
getBottom().y;
385 y_start = abs(y_bottom_bridge - y_start)/m_config.robot.body_length;
392 double x_start = FLT_MAX;
400 for(
int i=0 ; i<n ; i++){
405 if(r->m_currentGripJoint){
406 double x_r = r->m_currentGripJoint->GetAnchorA().x;
409 y_start = r->m_currentGripJoint->GetAnchorA().y;
414 y_end = r->m_currentGripJoint->GetAnchorA().y;
434 m_startP.Set(x_start, y_start);
435 m_endP.Set(x_end, y_end);
438 l+= distance(x_end, y_end, x_start, y_start);
441 l = l/m_config.robot.body_length;
448 std::string filename = m_config.logfile_path + m_config.logfile_name +
"_result.txt";
449 std::cout<<filename<<std::endl;
450 m_logFile.open(filename);
454 if(m_terrain.
getType()==V_TERRAIN){
455 m_logFile <<
"V-terrain parameters: \n";
456 m_logFile <<
" Width: "<< m_config.terrain.v_width <<
"\n";
457 m_logFile <<
" Height: "<< m_config.terrain.v_height <<
"\n";
458 m_logFile <<
" Angle: "<< m_config.terrain.v_angle*RAD_TO_DEG <<
" deg\n";
459 double l = m_terrain.
getVLength()/m_config.robot.body_length;
460 m_logFile <<
" total V path length: "<< std::to_string(l) <<
"\n \n";
463 m_logFile <<
" bottom: "<< std::to_string(m_terrain.
getBottom().x) <<
", "<< std::to_string(m_terrain.
getBottom().y)<<
"\n \n";
468 m_logFile <<
"Simulation parameters: \n";
471 m_logFile <<
" Gaussian delay "<<
" \n";
472 m_logFile <<
" standard deviation "<< m_std_dev <<
" \n";
473 m_logFile << std::fixed <<
" seed "<< m_seed <<
" \n";
475 m_logFile <<
" Delay between robots: "<< std::to_string(m_config.simulation.robot_delay) <<
" s\n";
476 m_logFile <<
" World gravity: "<< std::to_string(m_config.simulation.gravity) <<
"\n";
477 m_logFile <<
" Max number of robots: "<< std::to_string(m_config.simulation.nb_robots) <<
"\n";
478 m_logFile <<
" Distance between robots: "<< std::to_string(m_config.simulation.robot_distance) <<
" body length\n";
479 m_logFile <<
" Phase shift between robots: "<< std::to_string(m_config.simulation.robot_phase) <<
" rad\n";
480 m_logFile <<
" Initial x position of the first robot: "<< std::to_string(m_config.simulation.robot_initial_posX) <<
" m\n";
481 m_logFile <<
" Initial distance of the robot from the edge of the V: "<< std::to_string((m_terrain.
getTopLeftCorner().x-m_config.simulation.robot_initial_posX)/m_config.robot.body_length) <<
" m\n";
482 m_logFile <<
" Bridge formation step duration: "<< std::to_string(m_elapsedTimeBridge) <<
" s\n\n";
483 m_logFile <<
" Bridge dissolution step duration: "<< std::to_string(m_elapsedTimeDissolution) <<
" s\n\n";
484 m_logFile <<
" Simulation duration: "<< std::to_string(m_elapsedTime) <<
" s\n\n";
487 m_logFile <<
"Controller parameters: \n";
488 m_logFile <<
" Angle limit before the robot is able to grab: "<< std::to_string(m_config.controller.angle_limit*RAD_TO_DEG ) <<
" deg\n";
489 m_logFile <<
" Delay in bridge state: "<< std::to_string(m_config.controller.bridge_delay) <<
" s\n";
490 m_logFile <<
" Delay in walking state: "<< std::to_string(m_config.controller.walk_delay) <<
" s\n";
491 m_logFile <<
" Movement bridge_duration before the robot is considered to push: "<< std::to_string(m_config.controller.time_before_pushing) <<
" s\n";
492 m_logFile <<
" Max robot in the window: "<< std::to_string(m_config.controller.max_robot_window) <<
" s\n";
493 m_logFile <<
" Stability condition: "<< std::to_string(m_config.controller.stability_condition) <<
" s\n\n";
496 m_logFile <<
"Robot parameters: \n";
497 m_logFile <<
" Robot body length "<< std::to_string(m_config.robot.body_length) <<
" m\n";
498 m_logFile <<
" Robot velocity "<< std::to_string(m_config.robot.speed) <<
" rad/s\n\n";
501 if(m_nbRobotsInBridge >0){
502 m_logFile <<
"Bridge parameters: \n";
503 if(m_terrain.
getType()==V_TERRAIN){
504 m_logFile <<
" New path length: "<< std::to_string(m_length) <<
"\n";
505 m_logFile <<
" Bridge height: "<< std::to_string(m_height) <<
"\n";
506 m_logFile <<
" Bridge start: "<< std::to_string(m_startP.x) <<
", "<< std::to_string(m_startP.y)<<
"\n";
507 m_logFile <<
" Bridge end: "<< std::to_string(m_endP.x) <<
", "<< std::to_string(m_endP.y)<<
"\n";
509 m_logFile <<
" Number of robots in the bridge: "<< std::to_string(m_nbRobotsInBridge) <<
"\n\n";
510 m_logFile <<
" Number of robots in bridge state: "<< std::to_string(m_nbRobotsInBridgeState) <<
"\n\n";
513 m_logFile <<
"The bridge is STABLE \n";
515 m_logFile <<
"Time to reach stable bridge: "<< std::to_string(t) <<
" s \n\n";
519 m_logFile <<
"Bridge stability has not been reached \n \n";
521 m_logFile <<
"Robots are stacking \n \n";
527 m_logFile <<
"No bridge has formed \n\n";
531 m_logFile <<
"Dissolution parameters: \n";
533 m_logFile <<
" Bridge dissolution has not been reached \n ";
534 m_logFile <<
" Number of robots in the bridge: "<< std::to_string(m_robotController.
getNbActiveRobots()) <<
"\n\n";
538 m_logFile <<
" The bridge has DISSOLVED \n";
540 m_logFile <<
" Time to reach bridge dissolution: "<< std::to_string(t) <<
" s \n\n";
541 m_logFile <<
" Number of robots blocked: "<< std::to_string(m_robotController.
getNbActiveRobots()) <<
"\n\n";
544 m_logFile <<
"Rq: All distances are expressed in body length unit but coordinates are not. \n";
547 printf(
"file closed \n");
551 std::string filename = m_config.logfile_path + m_config.logfile_name +
"_bridge.txt";
552 m_bridgeFile.open(filename);
553 m_bridgeFile <<
"Timestamp; robot ID; x coordinate; y coordinate; angle; current joint x; current joint y; previous joint x; previous joint y; it entry; age \n\n";
560 if(!m_bridgeFile.is_open()){
561 std::string filename = m_config.logfile_path + m_config.logfile_name +
"_bridge.txt";
562 m_bridgeFile.open(filename);
565 for (
int i=0; i<n; i++){
570 int age = m_currentIt - r->m_bridgeAge;
573 double x = r->
getBody()->GetPosition().x;
574 double y = r->
getBody()->GetPosition().y;
575 double a = r->
getBody()->GetAngle();
580 if(r->m_currentGripJoint){
581 x_cj = r->m_currentGripJoint->GetAnchorA().x;
582 y_cj = r->m_currentGripJoint->GetAnchorA().y;
591 m_bridgeFile << m_currentIt <<
"; "<<
id <<
"; "<< x<<
"; "<< y <<
"; "<< a<<
"; "<<x_cj<<
"; "<<y_cj<<
"; "<<x_pj<<
"; "<<y_pj<<
"; "<<r->m_bridgeAge<<
"; "<<age<<
"\n";
601 window.clear(sf::Color::White);
603 m_robotController.
drawRobots(window, m_to_px);
607 sf::Image Screen = window.capture();
608 std::string filename = m_config.logfile_path + m_config.logfile_name +
"_formation_" + std::to_string(m_currentIt) +
".jpg";
609 Screen.saveToFile(filename);
613 sf::Image Screen = window.capture();
614 std::string filename = m_config.logfile_path + m_config.logfile_name +
"_dissolution_" + std::to_string(m_currentIt) +
".jpg";
615 Screen.saveToFile(filename);
void drawBody(sf::RenderWindow &window)
bool robotStacking(Robot *r, float posX)
RobotController getController()
virtual b2Vec2 getTopRightCorner()
double getDissolutionTime()
sf::RenderWindow * getWindow()
int getNbRobots(e_state s)
Robot * getRobotWithId(int id)
void setBridgeStability(bool stable)
Implementation of the Demo class and the MyContactListener_v2 class.
void drawRobots(sf::RenderWindow &window, double m_to_px)
Robot * getRobot(int pos_id)
virtual b2Vec2 getBottom()
virtual b2Vec2 getTopLeftCorner()
bool createRobot(b2World *world, int delay, double posX, double posY, double angle=0)
void create(b2World *world, sf::RenderWindow &window, config::sTerrain terrainParam, int WINDOW_X_PX, double bodyLength=1)
void createBody(b2World *world)
bool addRobotWithDistance()
void setScale(double m_to_px)
Demo(b2World *m_world, config::sConfig cfg)
double getStabilizationTime()
void takeScreenshot(bool draw, int step)
b2PrismaticJoint * m_previousGripJoint
double getNewPathLength()