g2o
Loading...
Searching...
No Matches
test_simulator2d.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 <fstream>
29#include <iostream>
30#include <sstream>
31
34#include "g2o/stuff/sampler.h"
35#include "simulator2d.h"
36
37using namespace g2o;
38using namespace std;
39using namespace Eigen;
40
41int main(int argc, char** argv) {
42 CommandArgs arg;
43 int nlandmarks;
44 int simSteps;
45 double worldSize;
46 bool hasOdom;
47 bool hasPoseSensor;
48 bool hasPointSensor;
49 bool hasPointBearingSensor;
50 bool hasCompass;
51 bool hasGPS;
52
53 bool hasSegmentSensor;
54 int nSegments;
55 int segmentGridSize;
56 double minSegmentLength, maxSegmentLength;
57
58 std::string outputFilename;
59 arg.param("nlandmarks", nlandmarks, 100, "number of landmarks in the map");
60 arg.param("nSegments", nSegments, 1000, "number of segments");
61 arg.param("segmentGridSize", segmentGridSize, 50,
62 "number of cells of the grid where to align the segments");
63 arg.param("minSegmentLength", minSegmentLength, 0.5,
64 "minimal Length of a segment in the world");
65 arg.param("maxSegmentLength", maxSegmentLength, 3,
66 "maximal Length of a segment in the world");
67
68 arg.param("simSteps", simSteps, 100, "number of simulation steps");
69 arg.param("worldSize", worldSize, 25.0, "size of the world");
70 arg.param("hasOdom", hasOdom, false, "the robot has an odometry");
71 arg.param("hasPointSensor", hasPointSensor, false,
72 "the robot has a point sensor");
73 arg.param("hasPointBearingSensor", hasPointBearingSensor, false,
74 "the robot has a point bearing sensor");
75 arg.param("hasPoseSensor", hasPoseSensor, false,
76 "the robot has a pose sensor");
77 arg.param("hasCompass", hasCompass, false, "the robot has a compass");
78 arg.param("hasGPS", hasGPS, false, "the robot has a GPS");
79 arg.param("hasSegmentSensor", hasSegmentSensor, false,
80 "the robot has a segment sensor");
81 arg.paramLeftOver("graph-output", outputFilename, "simulator_out.g2o",
82 "graph file which will be written", true);
83
84 arg.parseArgs(argc, argv);
85
86 std::mt19937 generator;
87 OptimizableGraph graph;
88 World world(&graph);
89 for (int i = 0; i < nlandmarks; i++) {
91 double x = sampleUniform(-.5, .5, &generator) * (worldSize + 5);
92 double y = sampleUniform(-.5, .5, &generator) * (worldSize + 5);
93 landmark->vertex()->setEstimate(Vector2d(x, y));
94 world.addWorldObject(landmark);
95 }
96
97 cerr << "nSegments = " << nSegments << endl;
98
99 for (int i = 0; i < nSegments; i++) {
101 int ix = sampleUniform(-segmentGridSize, segmentGridSize, &generator);
102 int iy = sampleUniform(-segmentGridSize, segmentGridSize, &generator);
103 int ith = sampleUniform(0, 3, &generator);
104 double th = (M_PI / 2) * ith;
105 th = atan2(sin(th), cos(th));
106 double xc = ix * (worldSize / segmentGridSize);
107 double yc = iy * (worldSize / segmentGridSize);
108
109 double l2 = sampleUniform(minSegmentLength, maxSegmentLength, &generator);
110
111 double x1 = xc + cos(th) * l2;
112 double y1 = yc + sin(th) * l2;
113 double x2 = xc - cos(th) * l2;
114 double y2 = yc - sin(th) * l2;
115
116 segment->vertex()->setEstimateP1(Vector2d(x1, y1));
117 segment->vertex()->setEstimateP2(Vector2d(x2, y2));
118 world.addWorldObject(segment);
119 }
120
121 Robot2D robot(&world, "myRobot");
122 world.addRobot(&robot);
123
124 stringstream ss;
125 ss << "-ws" << worldSize;
126 ss << "-nl" << nlandmarks;
127 ss << "-steps" << simSteps;
128
129 if (hasOdom) {
130 SensorOdometry2D* odometrySensor = new SensorOdometry2D("odometry");
131 robot.addSensor(odometrySensor);
132 Matrix3d odomInfo = odometrySensor->information();
133 odomInfo.setIdentity();
134 odomInfo *= 500;
135 odomInfo(2, 2) = 5000;
136 odometrySensor->setInformation(odomInfo);
137 ss << "-odom";
138 }
139
140 if (hasPoseSensor) {
141 SensorPose2D* poseSensor = new SensorPose2D("poseSensor");
142 robot.addSensor(poseSensor);
143 Matrix3d poseInfo = poseSensor->information();
144 poseInfo.setIdentity();
145 poseInfo *= 500;
146 poseInfo(2, 2) = 5000;
147 poseSensor->setInformation(poseInfo);
148 ss << "-pose";
149 }
150
151 if (hasPointSensor) {
152 SensorPointXY* pointSensor = new SensorPointXY("pointSensor");
153 robot.addSensor(pointSensor);
154 Matrix2d pointInfo = pointSensor->information();
155 pointInfo.setIdentity();
156 pointInfo *= 1000;
157 pointSensor->setInformation(pointInfo);
158 pointSensor->setFov(0.75 * M_PI);
159 ss << "-pointXY";
160 }
161
162 if (hasPointBearingSensor) {
163 SensorPointXYBearing* bearingSensor =
164 new SensorPointXYBearing("bearingSensor");
165 robot.addSensor(bearingSensor);
166 bearingSensor->setInformation(bearingSensor->information() * 1000);
167 ss << "-pointBearing";
168 }
169
170 if (hasSegmentSensor) {
171 cerr << "creating Segment Sensor" << endl;
172 SensorSegment2D* segmentSensor = new SensorSegment2D("segmentSensor");
173 cerr << "segmentSensorCreated" << endl;
174 segmentSensor->setMaxRange(3);
175 segmentSensor->setMinRange(.1);
176 robot.addSensor(segmentSensor);
177 segmentSensor->setInformation(segmentSensor->information() * 1000);
178
179 SensorSegment2DLine* segmentSensorLine =
180 new SensorSegment2DLine("segmentSensorSensorLine");
181 segmentSensorLine->setMaxRange(3);
182 segmentSensorLine->setMinRange(.1);
183 robot.addSensor(segmentSensorLine);
184 Matrix2d m = segmentSensorLine->information();
185 m = m * 1000;
186 m(0, 0) *= 10;
187 segmentSensorLine->setInformation(m);
188
189 SensorSegment2DPointLine* segmentSensorPointLine =
190 new SensorSegment2DPointLine("segmentSensorSensorPointLine");
191 segmentSensorPointLine->setMaxRange(3);
192 segmentSensorPointLine->setMinRange(.1);
193 robot.addSensor(segmentSensorPointLine);
194 Matrix3d m3 = segmentSensorPointLine->information();
195 m3 = m3 * 1000;
196 m3(2, 2) *= 10;
197 segmentSensorPointLine->setInformation(m3);
198
199 ss << "-segment2d";
200 }
201
202 robot.move(SE2());
203 double pStraight = 0.7;
204 SE2 moveStraight;
205 moveStraight.setTranslation(Vector2d(1., 0.));
206 double pLeft = 0.15;
207 SE2 moveLeft;
208 moveLeft.setRotation(Rotation2Dd(M_PI / 2));
209 // double pRight=0.15;
210 SE2 moveRight;
211 moveRight.setRotation(Rotation2Dd(-M_PI / 2));
212
213 for (int i = 0; i < simSteps; i++) {
214 cerr << "m";
215 SE2 move;
216 SE2 pose = robot.pose();
217 double dtheta = -100;
218 Vector2d dt;
219 if (pose.translation().x() < -.5 * worldSize) {
220 dtheta = 0;
221 }
222
223 if (pose.translation().x() > .5 * worldSize) {
224 dtheta = -M_PI;
225 }
226
227 if (pose.translation().y() < -.5 * worldSize) {
228 dtheta = M_PI / 2;
229 }
230
231 if (pose.translation().y() > .5 * worldSize) {
232 dtheta = -M_PI / 2;
233 }
234 if (dtheta < -M_PI) {
235 // select a random move of the robot
236 double sampled = sampleUniform(0., 1., &generator);
237 if (sampled < pStraight)
238 move = moveStraight;
239 else if (sampled < pStraight + pLeft)
240 move = moveLeft;
241 else
242 move = moveRight;
243 } else {
244 double mTheta = dtheta - pose.rotation().angle();
245 move.setRotation(Rotation2Dd(mTheta));
246 if (move.rotation().angle() < std::numeric_limits<double>::epsilon()) {
247 move.setTranslation(Vector2d(1., 0.));
248 }
249 }
250 robot.relativeMove(move);
251 // do a sense
252 cerr << "s";
253 robot.sense();
254 }
255 // string fname=outputFilename + ss.str() + ".g2o";
256 ofstream testStream(outputFilename.c_str());
257 graph.save(testStream);
258
259 return 0;
260}
const InformationType & information()
Definition simulator.h:256
void setInformation(const InformationType &information_)
Definition simulator.h:251
Command line parsing of argc and argv.
bool parseArgs(int argc, char **argv, bool exitOnError=true)
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)
void setMinRange(double minRange_)
void setMaxRange(double maxRange_)
represent SE2
Definition se2.h:43
const Vector2 & translation() const
translational component
Definition se2.h:57
void setRotation(const Rotation2D &R_)
Definition se2.h:62
void setTranslation(const Vector2 &t_)
Definition se2.h:58
const Rotation2D & rotation() const
rotational component
Definition se2.h:61
bool addRobot(BaseRobot *robot)
Definition simulator.cpp:82
bool addWorldObject(BaseWorldObject *worldObject)
Definition simulator.cpp:91
int main()
Definition gicp_demo.cpp:44
Definition jet.h:938
double sampleUniform(double min, double max, std::mt19937 *generator)
Definition sampler.cpp:35
WorldObject< VertexPointXY > WorldObjectPointXY
WorldObject< VertexSegment2D > WorldObjectSegment2D
Robot< WorldObjectSE2 > Robot2D
Definition jet.h:876
virtual bool save(std::ostream &os, int level=0) const
save the graph to a stream. Again uses the Factory system.