Army ant simulation
Demo.cpp
1 /*
2  * Demo.cpp
3  *
4  * Created on: 6 Nov 2018
5  * Author: lucie
6  *
7  * Update 01/22/2019:
8  * - change in writeBridgeFile()
9  * Robot position
10  * double x = r->getBody()->GetPosition().x/m_bodyLength; <-- r->getBody()->GetPosition().x;
11  * same for y
12  * - change in demoLoop()
13  * now when visualization is off, the simulation exit when the stability condition has been reached
14  * while (m_elapsedTime < m_config.simulation.duration) <-- while (m_elapsedTime < m_config.simulation.duration && !m_robotController.isBridgeStable() )
15  *
16  * Update 01/24/2019:
17  * - Added the dissolution phase: changed cfg.simulation.duration <-- cfg.simulation.bridge_duration, add cfg.simulation.dissolution_duration
18  * - In Demo::demoLoop() added the while (m_elapsedTime < m_config.simulation.dissolution_duration + m_config.simulation.bridge_duration)
19  * - In Demo::writeResultFile() added the /Dissolution parameters /
20  * - Added in .h double m_elapsedTimeDissolution = 0;
21  * double m_elapsedTimeBridge = 0;
22  * int m_currentIt = 0;
23  * int m_nbRobotsInBridge
24  *
25  * Update 02/8/2019:
26  * - Added the gaussian delay in Demo::demoLoop(). Can be activated by changing the gaussian_delay global variable to true
27  * //TODO: put it in global parameters so that it can be passed to the executable + standard deviation
28  */
29 
30 #include "Demo.h"
31 #include "helpers.h"
32 
33 #include <thread>
34 #include <math.h>
35 
36 bool distance_from_bottom = false;
37 
38 bool gaussian_delay = true;
39 bool periodic_delay = false;
40 
41 Demo::Demo(b2World* world, config::sConfig cfg){
42  m_world = world;
43  m_config = cfg;
44 // m_tex.create(m_config.window.WINDOW_X_PX, m_config.window.WINDOW_Y_PX);
45 
46 // m_delay(delay), m_maxRobots(nb_robots)
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));
50 
51  m_terrain.create(m_world, window, m_config.terrain, m_config.window.WINDOW_X_PX, m_config.robot.body_length );
52  m_terrain.createBody(m_world);
53  m_terrain.drawBody(window);
54  m_to_px = m_terrain.getScale();
55 
57  if(distance_from_bottom){
58  float V_slope = m_terrain.getVLength()/2;
59  m_config.simulation.robot_initial_posX = m_terrain.getTopLeftCorner().x + V_slope - m_config.simulation.robot_initial_posX*m_config.robot.body_length;
60  }
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;
63  }
64 
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;
68 
69  m_robotController.create(m_config.controller, m_config.robot, m_terrain.getBody());
70  m_robotController.setScale(m_to_px);
71  myContactListener = new MyContactListener_v2(m_robotController);
72 
73  if(gaussian_delay){
74  m_gauss_delay = std::normal_distribution<double>(m_config.simulation.robot_delay,m_std_dev);
75  m_seed = m_rd();// 2954034953.000000 ;//
76  m_gen.seed(m_seed);
77 // m_gen.seed(3.5);
78  }
79 
80 }
81 
82 Demo::~Demo() {
83  // TODO Auto-generated destructor stub
84 }
85 
86 void Demo::init(){
87  m_world->SetContactListener(myContactListener);
88  window.setFramerateLimit(60);
90 
91 }
92 
93 //Main demoLoop called in the main file: The demoLoop is structured in two cases: if the visualization is activated or not.
94 Both cases are then almost identical apart from the simulation part.
96 
97  // Case 1: the visualization is activated. It can be activated/deactivated by giving the right argument to the function (\ref param)
98  if(m_config.simulation.visualization){
99  // SFML event loop
100  while (window.isOpen())
101  {
102  // check all the window's events that were triggered since the last iteration of the loop
103  sf::Event event;
104  while (window.pollEvent(event))
105  {
106  // "close requested" event: we close the window
107  if (event.type == sf::Event::Closed)
108  window.close();
109 
110  // In case of visualization, a screenshot of the window can be taken anytime when typing the S key
111  if (event.key.code == sf::Keyboard::S)
112  {
113  sf::Image Screen = window.capture();
114  std::string name = "screenshot_" + std::to_string(m_elapsedTime) + ".jpg";
115  Screen.saveToFile(name);
116  }
117  }
118 
119  // First simulation step: Bridge formation. The bridge formation duration is defined by m_config.simulation.bridge_duration
120  // but is ended prematurely if a stacking situation is observed
121  if(m_elapsedTime < m_config.simulation.bridge_duration && !m_stacking){
122 
123  //This is where the traffic control is defined: either using addRobotWithDelay() or addRobotWithDistance()
124  if(!addRobotWithDelay()){
125  m_stacking = true;
126  printf("robot stacking \n");
127  // m_bridgeFile.close();
128  continue;
129  }
130  m_robotController.step(window.getSize().x);
131  m_world->Step(1.f/60.f, 100, 100);
132  m_robotController.removeRobot();
133 
134  // Drawing part (on SFML window)
135  window.clear(sf::Color::White);
136  m_terrain.drawBody(window);
137  m_robotController.drawRobots(window, m_to_px);
138  window.display();
139 
140  writeBridgeFile();
141 
142  // Save a screenshot every 600 iteration, ie every 10 s of real-time at 60 FPS
143  if(m_currentIt % 600 == 0){
144  takeScreenshot(false, 1);
145  }
146 
147  m_elapsedTime += 1.f/FPS;
148  m_currentIt ++;
149  if(!m_stableBridge){
150  m_stableBridge = m_robotController.isBridgeStable();
151  }
152  if(periodic_delay){
153  m_config.simulation.robot_delay = 2.5/(cos(PI/(18*60)*m_currentIt)*cos(PI/(18*60)*m_currentIt));
154  }
155  }
156 
157  // Second simulation step: Bridge dissolution. The bridge dissolution duration is defined by m_config.simulation.dissolution_duration
158  else if(m_elapsedTime < m_config.simulation.dissolution_duration + m_config.simulation.bridge_duration){
159 
160  m_robotController.step(window.getSize().x);
161  m_world->Step(1.f/60.f, 100, 100);
162  m_robotController.removeRobot();
163 
164  // Drawing part (on SFML window)
165  window.clear(sf::Color::White);
166  m_terrain.drawBody(window);
167  m_robotController.drawRobots(window, m_to_px);
168  window.display();
169 
170  writeBridgeFile();
171 
172  // Save a screenshot every 600 iteration, ie every 10 s of real-time at 60 FPS
173  if(m_currentIt % 600 == 0){
174  takeScreenshot(true, 2);
175  }
176 
177  m_elapsedTime += 1.f/FPS;
178  m_currentIt ++;
179  }
180 
181  else{
182  window.close();
183  break;
184  }
185  }
186  }
187 
188  // Case 2: the visualization is deactivated. It can be activated/deactivated by giving the right argument to the function (\ref param)
189  else{
190  /* First part of the simulation : bridge formation */
191  while (m_elapsedTime < m_config.simulation.bridge_duration ) //&& !m_robotController.isBridgeStable() )
192  {
193  // This is where the traffic control is defined: either using addRobotWithDelay() or addRobotWithDistance()
194  if(!addRobotWithDelay()){
195  m_stacking = true;
196  printf("robot stacking \n");
197 // m_bridgeFile.close();
198  break;
199  }
200 
201  m_robotController.step(window.getSize().x);
202  m_world->Step(1.f/60.f, 100, 100);
203  m_robotController.removeRobot();
204 
205  writeBridgeFile();
206 
207  // Save a screenshot every 600 iteration, ie every 10 s of real-time at 60 FPS
208  if(m_currentIt % 600 == 0){
209  takeScreenshot(true, 1);
210  }
211 
212  m_elapsedTime += 1.f/FPS;
213  m_currentIt ++;
214  if(!m_stableBridge){
215  m_stableBridge = m_robotController.isBridgeStable();
216  }
217  if(periodic_delay){
218  m_config.simulation.robot_delay = 2.5/(cos(PI/(18*60)*m_currentIt)*cos(PI/(18*60)*m_currentIt));
219  }
220  }
221 
222  // Get the number of robots in the final bridge
223  m_nbRobotsInBridgeState = m_robotController.getNbRobots(BRIDGE);
224  m_nbRobotsInBridge = m_nbRobotsInBridgeState + m_robotController.getNbRobotsBlocked();
225  m_elapsedTimeBridge = m_elapsedTime;
226  m_length = getNewPathLength();
227  m_height = getBridgeHeight();
228 
229  /* Second part of the simulation : bridge dissolution */
230  while (m_elapsedTime < m_config.simulation.dissolution_duration + m_config.simulation.bridge_duration) //&& !m_robotController.isBridgeStable() )
231  {
232 
233  m_robotController.step(window.getSize().x);
234  m_world->Step(1.f/60.f, 100, 100);
235  m_robotController.removeRobot();
236  writeBridgeFile();
237 
238  m_robotController.isBridgeDissolved();
239 
240  // Save a screenshot every 600 iteration, ie every 10 s of real-time at 60 FPS
241  if(m_currentIt % 600 == 0){
242  takeScreenshot(true, 2);
243  }
244 
245  m_elapsedTime += 1.f/FPS;
246  m_currentIt ++;
247  }
248  }
249 
250  printf("end loop \n");
251  m_bridgeFile.close();
259 }
260 
262 
263  if(m_nbRobots < m_config.simulation.nb_robots){
264  int final_it = int(60 * m_config.simulation.robot_delay) ; // at 60 fps
265  if(m_it > final_it){
266 // std::cout<< m_config.simulation.robot_delay<<std::endl;
267  if(m_nbRobots && m_robotController.robotStacking(m_robotController.getRobotWithId(m_nbRobots), m_config.simulation.robot_initial_posX)){
268  m_robotController.setBridgeStability(false);
269  return false;
270  }
271  m_robotController.createRobot(m_world, 0, m_config.simulation.robot_initial_posX, m_config.simulation.robot_initial_posY);
272  m_it = 0;
273  if(gaussian_delay){
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;
276  }
277  m_nbRobots++;
278 
279  if(m_nbRobots == 2){
280  m_config.simulation.robot_distance = (m_robotController.getRobot(0)->getPosition().x- m_robotController.getRobot(1)->getPosition().x)/m_config.robot.body_length;
281  int delay = m_robotController.getRobot(0)->getDelay();
282  /* If the first robot is flat, the phase shift is proportional to the delay remaining*/
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));
286  }
287  else{
288  m_config.simulation.robot_phase = moduloAngle(m_robotController.getRobot(0)->getAngle(), PI);
289  }
290  takeScreenshot(true, 1);
291  }
292  }
293  else{
294  m_it++;
295  }
296  }
297  return true;
298 }
299 
300 
302 
303  if(m_nbRobots == 0){
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;
307  m_nbRobots++;
308  return true;
309  }
310  else if(m_nbRobots < m_config.simulation.nb_robots){
311 
312  float distance = m_robotController.getRobotWithId(m_nbRobots)->getBody()->GetPosition().x;
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;
315 
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); // what is the better option: int or round ?
318  if(distance >= target && m_robotController.getRobotWithId(m_nbRobots)->getDelay()==delay){
319  float x = m_robotController.getRobotWithId(m_nbRobots)->getBody()->GetPosition().x - target;
320  if(m_robotController.createRobot(m_world, 0, x, m_config.simulation.robot_initial_posY)){
321  m_nbRobots++;
322  return true;
323  }
324  }
325 
326  }
327  else{
328  float angle = m_robotController.getRobotWithId(m_nbRobots)->getBody()->GetAngle();
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); // what is the better option: int or round ?
332  if(distance >= target && m_robotController.getRobotWithId(m_nbRobots)->getDelay()==delay){
333  float x = m_robotController.getRobotWithId(m_nbRobots)->getBody()->GetPosition().x - target;
334  if(m_robotController.createRobot(m_world, 0, x, m_config.simulation.robot_initial_posY)){
335  m_nbRobots++;
336  return true;
337  }
338  }
339  }
340  }
341  return false;
342 }
343 
345  return m_robotController;
346 }
347 
348 sf::RenderWindow* Demo::getWindow(){
349  sf::RenderWindow* ptrWind = &window;
350  return ptrWind;
351 }
352 
354  int n = m_robotController.getNbActiveRobots();
355  double x_start = FLT_MAX;
356  double y_start = 0;
357 
358  Robot* r;
359  for(int i=0 ; i<n ; i++){
360  r = m_robotController.getRobot(i);
361  if (r->getState()== BRIDGE){
362 
363  // test for first grip joint
364  if(r->m_currentGripJoint){
365  double x_r = r->m_currentGripJoint->GetAnchorA().x;
366  if(x_r < x_start){
367  x_start = x_r;
368  y_start = r->m_currentGripJoint->GetAnchorA().y;
369  }
370  }
371 
372  // test for second grip joint
373  if(r->m_previousGripJoint){
374  double x_r = r->m_previousGripJoint->GetAnchorA().x;
375  if(x_r < x_start){
376  x_start = x_r;
377  y_start = r->m_previousGripJoint->GetAnchorA().y;
378  }
379  }
380  }
381  }
382 
383  double y_bottom_bridge = m_terrain.getBottom().y;
384 
385  y_start = abs(y_bottom_bridge - y_start)/m_config.robot.body_length;
386 
387  return y_start;
388 }
389 
391  int n = m_robotController.getNbActiveRobots();
392  double x_start = FLT_MAX;
393  double y_start = 0;
394  double x_end = 0;
395  double y_end = 0;
396 
397  double l=0;
398 
399  Robot* r;
400  for(int i=0 ; i<n ; i++){
401  r = m_robotController.getRobot(i);
402  if (r->getState() == BRIDGE){
403 
404  // test for first grip joint
405  if(r->m_currentGripJoint){
406  double x_r = r->m_currentGripJoint->GetAnchorA().x;
407  if(x_r < x_start){
408  x_start = x_r;
409  y_start = r->m_currentGripJoint->GetAnchorA().y;
410  }
411 
412  if(x_r > x_end){
413  x_end = x_r;
414  y_end = r->m_currentGripJoint->GetAnchorA().y;
415  }
416  }
417 
418  // test for second grip joint
419  if(r->m_previousGripJoint){
420  double x_r = r->m_previousGripJoint->GetAnchorA().x;
421  if(x_r < x_start){
422  x_start = x_r;
423  y_start = r->m_previousGripJoint->GetAnchorA().y;
424  }
425 
426  if(x_r > x_end){
427  x_end = x_r;
428  y_end = r->m_previousGripJoint->GetAnchorA().y;
429  }
430  }
431  }
432  }
433 
434  m_startP.Set(x_start, y_start);
435  m_endP.Set(x_end, y_end);
436 
437  l = distance(m_terrain.getTopLeftCorner().x, m_terrain.getTopLeftCorner().y, x_start, y_start);
438  l+= distance(x_end, y_end, x_start, y_start);
439  l+= distance(m_terrain.getTopRightCorner().x, m_terrain.getTopRightCorner().y, x_end, y_end);
440 
441  l = l/m_config.robot.body_length;
442  return l;
443 
444 }
445 
447 
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);
451  double t;
452 
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";
461  m_logFile << " top right corner: "<< std::to_string(m_terrain.getTopRightCorner().x) << ", "<< std::to_string( m_terrain.getTopRightCorner().y)<< "\n";
462  m_logFile << " top left corner: "<< std::to_string(m_terrain.getTopLeftCorner().x) << ", "<< std::to_string( m_terrain.getTopLeftCorner().y)<< "\n";
463  m_logFile << " bottom: "<< std::to_string(m_terrain.getBottom().x) << ", "<< std::to_string(m_terrain.getBottom().y)<< "\n \n";
464  }
465 
466 
468  m_logFile << "Simulation parameters: \n";
469 // m_logFile << " Robots entry point: "<< std::to_string(m_delay) << "s\n";
470  if(gaussian_delay){
471  m_logFile << " Gaussian delay "<< " \n";
472  m_logFile << " standard deviation "<< m_std_dev << " \n";
473  m_logFile << std::fixed << " seed "<< m_seed << " \n";
474  }
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";
485 
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";
494 
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";
499 
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";
508  }
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";
511 
512  if(m_stableBridge){
513  m_logFile << "The bridge is STABLE \n";
514  t = m_robotController.getStabilizationTime();
515  m_logFile << "Time to reach stable bridge: "<< std::to_string(t) << " s \n\n";
516  }
517 
518  else{
519  m_logFile << "Bridge stability has not been reached \n \n";
520  if(m_stacking){
521  m_logFile << "Robots are stacking \n \n";
522  }
523  }
524  }
525 
526  else{
527  m_logFile << "No bridge has formed \n\n";
528  }
529 
531  m_logFile << "Dissolution parameters: \n";
532  if(m_robotController.getNbRobots(BRIDGE) > 0){
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";
535 
536  }
537  else{
538  m_logFile << " The bridge has DISSOLVED \n";
539  t=m_robotController.getDissolutionTime();
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";
542  }
543 
544  m_logFile << "Rq: All distances are expressed in body length unit but coordinates are not. \n";
545  m_logFile.close();
546 
547  printf("file closed \n");
548 }
549 
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";
554 }
555 
557  if(m_robotController.m_bridgeEntry){
558  m_robotController.m_bridgeEntry = false;
559 // std::cout<<"write in bridge file "<<std::endl;
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);
563  }
564  int n = m_robotController.getNbActiveRobots();
565  for (int i=0; i<n; i++){
566  Robot* r = m_robotController.getRobot(i);
567  if(r->getState()==BRIDGE){
569  int id = r->getId();
570  int age = m_currentIt - r->m_bridgeAge; //TODO: check that current it of demo match the one of robot controller
571 
573  double x = r->getBody()->GetPosition().x;
574  double y = r->getBody()->GetPosition().y;
575  double a = r->getBody()->GetAngle();
576 
578  float x_cj = 0;
579  float y_cj = 0;
580  if(r->m_currentGripJoint){
581  x_cj = r->m_currentGripJoint->GetAnchorA().x;
582  y_cj = r->m_currentGripJoint->GetAnchorA().y;
583  }
584  float x_pj = 0;
585  float y_pj = 0;
586  if(r->m_previousGripJoint){
587  x_pj = r->m_previousGripJoint->GetAnchorA().x;
588  y_pj = r->m_previousGripJoint->GetAnchorA().y;
589  }
590 
591  m_bridgeFile << m_currentIt << "; "<< id << "; "<< x<< "; "<< y << "; "<< a<< "; "<<x_cj<< "; "<<y_cj<< "; "<<x_pj<< "; "<<y_pj<<"; "<<r->m_bridgeAge<<"; "<<age<<"\n";
592 
593  }
594  }
595  }
596 }
597 
598 void Demo::takeScreenshot(bool draw, int step){
599 
600  if(draw){
601  window.clear(sf::Color::White);
602  m_terrain.drawBody(window);
603  m_robotController.drawRobots(window, m_to_px);
604  }
605 
606  if(step==1){
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);
610  }
611 
612  else if(step==2){
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);
616  }
617 
618 }
void drawBody(sf::RenderWindow &window)
Definition: BoxTerrain.cpp:68
bool robotStacking(Robot *r, float posX)
RobotController getController()
Definition: Demo.cpp:344
void init()
Definition: Demo.cpp:86
double getBridgeHeight()
Definition: Demo.cpp:353
virtual b2Vec2 getTopRightCorner()
Definition: Terrain.cpp:97
double getDissolutionTime()
sf::RenderWindow * getWindow()
Definition: Demo.cpp:348
int getNbRobots(e_state s)
Robot * getRobotWithId(int id)
void setBridgeStability(bool stable)
e_terrain_type getType()
Definition: BoxTerrain.cpp:90
Implementation of the Demo class and the MyContactListener_v2 class.
int getId()
Definition: Robot.cpp:1053
void drawRobots(sf::RenderWindow &window, double m_to_px)
double getAngle()
Definition: Robot.cpp:1037
Robot * getRobot(int pos_id)
const double getScale()
Definition: Terrain.cpp:88
virtual b2Vec2 getBottom()
Definition: Terrain.cpp:98
bool addRobotWithDelay()
Definition: Demo.cpp:261
virtual b2Vec2 getTopLeftCorner()
Definition: Terrain.cpp:96
bool createRobot(b2World *world, int delay, double posX, double posY, double angle=0)
void writeBridgeFile()
Definition: Demo.cpp:556
b2Body * getBody()
Definition: Terrain.cpp:84
Definition: Robot.h:40
void create(b2World *world, sf::RenderWindow &window, config::sTerrain terrainParam, int WINDOW_X_PX, double bodyLength=1)
Definition: BoxTerrain.cpp:26
e_state getState()
Definition: Robot.cpp:1069
void createBody(b2World *world)
Definition: BoxTerrain.cpp:35
void createBridgeFile()
Definition: Demo.cpp:550
bool addRobotWithDistance()
Definition: Demo.cpp:301
void demoLoop()
Definition: Demo.cpp:95
double getVLength()
Definition: Terrain.h:67
int getDelay()
Definition: Robot.cpp:1048
b2Body * getBody()
Definition: Robot.cpp:1041
void step(double end_x)
void setScale(double m_to_px)
Demo(b2World *m_world, config::sConfig cfg)
Definition: Demo.cpp:41
double getStabilizationTime()
void takeScreenshot(bool draw, int step)
Definition: Demo.cpp:598
b2PrismaticJoint * m_previousGripJoint
Definition: Robot.h:287
void writeResultFile()
Definition: Demo.cpp:446
double getNewPathLength()
Definition: Demo.cpp:390
b2Vec2 getPosition()
Definition: Robot.cpp:1065