g2o
simulator2d_segment.cpp
Go to the documentation of this file.
1 // g2o - General Graph Optimization
2 // Copyright (C) 2011 G. Grisetti, R. Kuemmerle, W. Burgard
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <cstdlib>
28 #include "g2o/stuff/command_args.h"
29 #include "g2o/stuff/sampler.h"
30 #include "simulator2d.h"
32 #include <iostream>
33 #include <fstream>
34 #include <sstream>
35 
36 using namespace g2o;
37 using namespace std;
38 
39 
40 int main(int argc, char** argv) {
41  CommandArgs arg;
42  int nlandmarks;
43  int nSegments;
44  int simSteps;
45  double worldSize;
46  bool hasOdom;
47  bool hasPoseSensor;
48  bool hasPointSensor;
49  bool hasPointBearingSensor;
50  bool hasSegmentSensor;
51  bool hasCompass;
52  bool hasGPS;
53 
54  int segmentGridSize;
55  double minSegmentLenght, maxSegmentLenght;
56 
57  std::string outputFilename;
58  arg.param("simSteps", simSteps, 100, "number of simulation steps");
59  arg.param("nLandmarks", nlandmarks, 1000, "number of landmarks");
60  arg.param("nSegments", nSegments, 1000, "number of segments");
61  arg.param("segmentGridSize", segmentGridSize, 50, "number of cells of the grid where to align the segments");
62  arg.param("minSegmentLenght", minSegmentLenght, 0.5, "minimal lenght of a segment in the world");
63  arg.param("maxSegmentLenght", maxSegmentLenght, 3, "maximal lenght of a segment in the world");
64  arg.param("worldSize", worldSize, 25.0, "size of the world");
65  arg.param("hasOdom", hasOdom, false, "the robot has an odometry" );
66  arg.param("hasPointSensor", hasPointSensor, false, "the robot has a point sensor" );
67  arg.param("hasPointBearingSensor", hasPointBearingSensor, false, "the robot has a point bearing sensor" );
68  arg.param("hasPoseSensor", hasPoseSensor, false, "the robot has a pose sensor" );
69  arg.param("hasCompass", hasCompass, false, "the robot has a compass");
70  arg.param("hasGPS", hasGPS, false, "the robot has a GPS");
71  arg.param("hasSegmentSensor", hasSegmentSensor, false, "the robot has a segment sensor" );
72  arg.paramLeftOver("graph-output", outputFilename, "simulator_out.g2o", "graph file which will be written", true);
73 
74 
75  arg.parseArgs(argc, argv);
76 
77  std::mt19937 generator;
79  World world(&graph);
80  for (int i=0; i<nlandmarks; i++){
81  WorldObjectPointXY * landmark = new WorldObjectPointXY;
82  double x = sampleUniform(-.5,.5, &generator)*worldSize;
83  double y = sampleUniform(-.5,.5, &generator)*worldSize;
84  landmark->vertex()->setEstimate(Vector2d(x,y));
85  world.addWorldObject(landmark);
86  }
87 
88  cerr << "nSegments = " << nSegments << endl;
89 
90  for (int i=0; i<nSegments; i++){
92  int ix = sampleUniform(-segmentGridSize,segmentGridSize, &generator);
93  int iy = sampleUniform(-segmentGridSize,segmentGridSize, &generator);
94  int ith = sampleUniform(0,3, &generator);
95  double th= (M_PI/2)*ith;
96  th=atan2(sin(th),cos(th));
97  double xc = ix*(worldSize/segmentGridSize);
98  double yc = iy*(worldSize/segmentGridSize);
99 
100  double l2 = sampleUniform(minSegmentLenght, maxSegmentLenght, &generator);
101 
102  double x1 = xc + cos(th)*l2;
103  double y1 = yc + sin(th)*l2;
104  double x2 = xc - cos(th)*l2;
105  double y2 = yc - sin(th)*l2;
106 
107 
108  segment->vertex()->setEstimateP1(Vector2d(x1,y1));
109  segment->vertex()->setEstimateP2(Vector2d(x2,y2));
110  world.addWorldObject(segment);
111  }
112 
113 
114  Robot2D robot(&world, "myRobot");
115  world.addRobot(&robot);
116 
117 
118  stringstream ss;
119  ss << "-ws" << worldSize;
120  ss << "-nl" << nlandmarks;
121  ss << "-steps" << simSteps;
122 
123  if (hasOdom) {
124  SensorOdometry2D* odometrySensor=new SensorOdometry2D("odometry");
125  robot.addSensor(odometrySensor);
126  Matrix3d odomInfo = odometrySensor->information();
127  odomInfo.setIdentity();
128  odomInfo*=100;
129  odomInfo(2,2)=1000;
130  odometrySensor->setInformation(odomInfo);
131  ss << "-odom";
132  }
133 
134  if (hasPoseSensor) {
135  SensorPose2D* poseSensor = new SensorPose2D("poseSensor");
136  robot.addSensor(poseSensor);
137  Matrix3d poseInfo = poseSensor->information();
138  poseInfo.setIdentity();
139  poseInfo*=100;
140  poseInfo(2,2)=1000;
141  poseSensor->setInformation(poseInfo);
142  ss << "-pose";
143  }
144 
145  if (hasPointSensor) {
146  SensorPointXY* pointSensor = new SensorPointXY("pointSensor");
147  robot.addSensor(pointSensor);
148  Matrix2d pointInfo = pointSensor->information();
149  pointInfo.setIdentity();
150  pointInfo*=100;
151  pointSensor->setInformation(pointInfo);
152  ss << "-pointXY";
153  }
154 
155  if (hasPointBearingSensor) {
156  SensorPointXYBearing* bearingSensor = new SensorPointXYBearing("bearingSensor");
157  robot.addSensor(bearingSensor);
158  bearingSensor->setInformation(bearingSensor->information()*1000);
159  ss << "-pointBearing";
160  }
161 
162  if (hasSegmentSensor) {
163  SensorSegment2D* segmentSensor = new SensorSegment2D("segmentSensorSensor");
164  segmentSensor->setMaxRange(3);
165  segmentSensor->setMinRange(.1);
166  robot.addSensor(segmentSensor);
167  segmentSensor->setInformation(segmentSensor->information()*1000);
168 
169  SensorSegment2DLine* segmentSensorLine = new SensorSegment2DLine("segmentSensorSensorLine");
170  segmentSensorLine->setMaxRange(3);
171  segmentSensorLine->setMinRange(.1);
172  robot.addSensor(segmentSensorLine);
173  Matrix2d m=segmentSensorLine->information();
174  m=m*1000;
175  m(0,0)*=10;
176  segmentSensorLine->setInformation(m);
177 
178  SensorSegment2DPointLine* segmentSensorPointLine = new SensorSegment2DPointLine("segmentSensorSensorPointLine");
179  segmentSensorPointLine->setMaxRange(3);
180  segmentSensorPointLine->setMinRange(.1);
181  robot.addSensor(segmentSensorPointLine);
182  Matrix3d m3=segmentSensorPointLine->information();
183  m3=m3*1000;
184  m3(3,3)*=10;
185  segmentSensorPointLine->setInformation(m3);
186 
187  ss << "-segment2d";
188  }
189 
190 
191 
192  robot.move(SE2());
193  double pStraight=0.7;
194  SE2 moveStraight; moveStraight.setTranslation(Vector2d(1., 0.));
195  double pLeft=0.15;
196  SE2 moveLeft; moveLeft.setRotation(Rotation2Dd(M_PI/2));
197  //double pRight=0.15;
198  SE2 moveRight; moveRight.setRotation(Rotation2Dd(-M_PI/2));
199 
200  for (int i=0; i<simSteps; i++){
201  cerr << "m";
202  SE2 move;
203  SE2 pose=robot.pose();
204  double dtheta=-100;
205  Vector2d dt;
206  if (pose.translation().x() < -.5*worldSize){
207  dtheta = 0;
208  }
209 
210  if (pose.translation().x() > .5*worldSize){
211  dtheta = -M_PI;
212  }
213 
214  if (pose.translation().y() < -.5*worldSize){
215  dtheta = M_PI/2;
216  }
217 
218  if (pose.translation().y() > .5*worldSize){
219  dtheta = -M_PI/2;
220  }
221  if (dtheta< -M_PI) {
222  // select a random move of the robot
223  double sampled=sampleUniform(0.,1.,&generator);
224  if (sampled<pStraight)
225  move=moveStraight;
226  else if (sampled<pStraight+pLeft)
227  move=moveLeft;
228  else
229  move=moveRight;
230  } else {
231  double mTheta=dtheta-pose.rotation().angle();
232  move.setRotation(Rotation2Dd(mTheta));
233  if (move.rotation().angle()<std::numeric_limits<double>::epsilon()){
234  move.setTranslation(Vector2d(1., 0.));
235  }
236  }
237  robot.relativeMove(move);
238  // do a sense
239  cerr << "s";
240  robot.sense();
241  }
242  //string fname=outputFilename + ss.str() + ".g2o";
243  ofstream testStream(outputFilename.c_str());
244  graph.save(testStream);
245 
246  return 0;
247 }
void setMinRange(double minRange_)
Command line parsing of argc and argv.
Definition: command_args.h:46
WorldObject< VertexSegment2D > WorldObjectSegment2D
bool addSensor(BaseSensor *sensor)
Definition: simulator.cpp:51
virtual void sense()
Definition: simulator.cpp:61
represent SE2
Definition: se2.h:40
bool addRobot(BaseRobot *robot)
Definition: simulator.cpp:82
WorldObject< VertexPointXY > WorldObjectPointXY
void setMaxRange(double maxRange_)
bool parseArgs(int argc, char **argv, bool exitOnError=true)
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.
const Eigen::Rotation2Dd & rotation() const
rotational component
Definition: se2.h:58
const InformationType & information()
Definition: simulator.h:226
void paramLeftOver(const std::string &name, std::string &p, const std::string &defValue, const std::string &desc, bool optional=false)
void param(const std::string &name, bool &p, bool defValue, const std::string &desc)
const PoseType & pose() const
Definition: simulator.h:120
virtual void relativeMove(const PoseType &movement_)
Definition: simulator.h:104
bool addWorldObject(BaseWorldObject *worldObject)
Definition: simulator.cpp:90
const Vector2D & translation() const
translational component
Definition: se2.h:54
int main(int argc, char **argv)
VertexType * vertex()
Definition: simulator.h:72
virtual void move(const PoseType &pose_)
Definition: simulator.h:109
#define M_PI
Definition: misc.h:34
void setInformation(const InformationType &information_)
Definition: simulator.h:221
Protocol The SLAM executable accepts such as solving the and retrieving or vertices in the graph
Definition: protocol.txt:7
void setTranslation(const Vector2D &t_)
Definition: se2.h:55
void setRotation(const Eigen::Rotation2Dd &R_)
Definition: se2.h:59
double sampleUniform(double min, double max, std::mt19937 *generator)
Definition: sampler.cpp:35