g2o
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
g2o::tutorial::Simulator Class Reference

#include <simulator.h>

Classes

struct  GridEdge
 odometry constraint More...
 
struct  GridPose
 
struct  Landmark
 simulated landmark More...
 
struct  LandmarkEdge
 

Public Types

using LandmarkVector = std::vector< Landmark >
 
using LandmarkPtrVector = std::vector< Landmark * >
 
using PosesVector = std::vector< GridPose >
 
using GridEdgeVector = std::vector< GridEdge >
 
using LandmarkEdgeVector = std::vector< LandmarkEdge >
 

Public Member Functions

 Simulator ()
 
 ~Simulator ()
 
void simulate (int numPoses, const SE2 &sensorOffset=SE2())
 
const PosesVectorposes () const
 
const LandmarkVectorlandmarks () const
 
const GridEdgeVectorodometry () const
 
const LandmarkEdgeVectorlandmarkObservations () const
 

Protected Member Functions

GridPose generateNewPose (const GridPose &prev, const SE2 &trueMotion, const Eigen::Vector2d &transNoise, double rotNoise)
 
SE2 getMotion (int motionDirection, double stepLen)
 
SE2 sampleTransformation (const SE2 &trueMotion_, const Eigen::Vector2d &transNoise, double rotNoise)
 

Protected Attributes

PosesVector _poses
 
LandmarkVector _landmarks
 
GridEdgeVector _odometry
 
LandmarkEdgeVector _landmarkObservations
 

Detailed Description

Definition at line 39 of file simulator.h.

Member Typedef Documentation

◆ GridEdgeVector

Definition at line 80 of file simulator.h.

◆ LandmarkEdgeVector

Definition at line 90 of file simulator.h.

◆ LandmarkPtrVector

Definition at line 55 of file simulator.h.

◆ LandmarkVector

Definition at line 54 of file simulator.h.

◆ PosesVector

Definition at line 67 of file simulator.h.

Constructor & Destructor Documentation

◆ Simulator()

Simulator::Simulator ( )

Definition at line 50 of file simulator.cpp.

50 {
51 time_t seed = time(0);
52 Sampler::seedRand(static_cast<unsigned int>(seed));
53}
static void seedRand()
Definition sampler.h:109

References g2o::Sampler::seedRand().

◆ ~Simulator()

Simulator::~Simulator ( )

Definition at line 55 of file simulator.cpp.

55{}

Member Function Documentation

◆ generateNewPose()

Simulator::GridPose Simulator::generateNewPose ( const GridPose prev,
const SE2 trueMotion,
const Eigen::Vector2d &  transNoise,
double  rotNoise 
)
protected

Definition at line 292 of file simulator.cpp.

294 {
295 Simulator::GridPose nextPose;
296 nextPose.id = prev.id + 1;
297 nextPose.truePose = prev.truePose * trueMotion;
298 SE2 noiseMotion = sampleTransformation(trueMotion, transNoise, rotNoise);
299 nextPose.simulatorPose = prev.simulatorPose * noiseMotion;
300 return nextPose;
301}
SE2 sampleTransformation(const SE2 &trueMotion_, const Eigen::Vector2d &transNoise, double rotNoise)

References g2o::tutorial::Simulator::GridPose::id, sampleTransformation(), g2o::tutorial::Simulator::GridPose::simulatorPose, and g2o::tutorial::Simulator::GridPose::truePose.

Referenced by simulate().

◆ getMotion()

SE2 Simulator::getMotion ( int  motionDirection,
double  stepLen 
)
protected

Definition at line 303 of file simulator.cpp.

303 {
304 switch (motionDirection) {
305 case MO_LEFT:
306 return SE2(stepLen, 0, 0.5 * M_PI);
307 case MO_RIGHT:
308 return SE2(stepLen, 0, -0.5 * M_PI);
309 default:
310 cerr << "Unknown motion direction" << endl;
311 return SE2(stepLen, 0, -0.5 * M_PI);
312 }
313}
MO_LEFT
Definition simulator.h:41
MO_RIGHT
Definition simulator.h:41

References MO_LEFT, and MO_RIGHT.

Referenced by simulate().

◆ landmarkObservations()

const LandmarkEdgeVector & g2o::tutorial::Simulator::landmarkObservations ( ) const
inline

Definition at line 101 of file simulator.h.

101 {
103 }
LandmarkEdgeVector _landmarkObservations
Definition simulator.h:109

◆ landmarks()

const LandmarkVector & g2o::tutorial::Simulator::landmarks ( ) const
inline

Definition at line 99 of file simulator.h.

99{ return _landmarks; }
LandmarkVector _landmarks
Definition simulator.h:107

Referenced by simulate().

◆ odometry()

const GridEdgeVector & g2o::tutorial::Simulator::odometry ( ) const
inline

Definition at line 100 of file simulator.h.

100{ return _odometry; }
GridEdgeVector _odometry
Definition simulator.h:108

◆ poses()

const PosesVector & g2o::tutorial::Simulator::poses ( ) const
inline

Definition at line 98 of file simulator.h.

98{ return _poses; }

Referenced by simulate().

◆ sampleTransformation()

SE2 Simulator::sampleTransformation ( const SE2 trueMotion_,
const Eigen::Vector2d &  transNoise,
double  rotNoise 
)
protected

Definition at line 315 of file simulator.cpp.

317 {
318 Vector3d trueMotion = trueMotion_.toVector();
319 SE2 noiseMotion(trueMotion[0] + Sampler::gaussRand(0.0, transNoise[0]),
320 trueMotion[1] + Sampler::gaussRand(0.0, transNoise[1]),
321 trueMotion[2] + Sampler::gaussRand(0.0, rotNoise));
322 return noiseMotion;
323}
static double gaussRand(double mean, double sigma)
Definition sampler.h:89

References g2o::Sampler::gaussRand(), and g2o::tutorial::SE2::toVector().

Referenced by generateNewPose().

◆ simulate()

void Simulator::simulate ( int  numPoses,
const SE2 sensorOffset = SE2() 
)

Definition at line 57 of file simulator.cpp.

57 {
58 // simulate a robot observing landmarks while travelling on a grid
59 int steps = 5;
60 double stepLen = 1.0;
61 int boundArea = 50;
62
63 double maxSensorRangeLandmarks = 2.5 * stepLen;
64
65 int landMarksPerSquareMeter = 1;
66 double observationProb = 0.8;
67
68 int landmarksRange = 2;
69
70 Vector2d transNoise(0.05, 0.01);
71 double rotNoise = DEG2RAD(2.);
72 Vector2d landmarkNoise(0.05, 0.05);
73
74 Vector2d bound(boundArea, boundArea);
75
76 VectorXd probLimits;
77 probLimits.resize(MO_NUM_ELEMS);
78 for (int i = 0; i < probLimits.size(); ++i)
79 probLimits[i] = (i + 1) / (double)MO_NUM_ELEMS;
80
81 Matrix3d covariance;
82 covariance.fill(0.);
83 covariance(0, 0) = transNoise[0] * transNoise[0];
84 covariance(1, 1) = transNoise[1] * transNoise[1];
85 covariance(2, 2) = rotNoise * rotNoise;
86 Matrix3d information = covariance.inverse();
87
88 SE2 maxStepTransf(stepLen * steps, 0, 0);
90 poses.clear();
92 landmarks.clear();
93 Simulator::GridPose firstPose;
94 firstPose.id = 0;
95 firstPose.truePose = SE2(0, 0, 0);
96 firstPose.simulatorPose = SE2(0, 0, 0);
97 poses.push_back(firstPose);
98 cerr << "Simulator: sampling nodes ...";
99 while ((int)poses.size() < numNodes) {
100 // add straight motions
101 for (int i = 1; i < steps && (int)poses.size() < numNodes; ++i) {
102 Simulator::GridPose nextGridPose = generateNewPose(
103 poses.back(), SE2(stepLen, 0, 0), transNoise, rotNoise);
104 poses.push_back(nextGridPose);
105 }
106 if ((int)poses.size() == numNodes) break;
107
108 // sample a new motion direction
109 double sampleMove = Sampler::uniformRand(0., 1.);
110 int motionDirection = 0;
111 while (probLimits[motionDirection] < sampleMove &&
112 motionDirection + 1 < MO_NUM_ELEMS) {
113 motionDirection++;
114 }
115
116 SE2 nextMotionStep = getMotion(motionDirection, stepLen);
117 Simulator::GridPose nextGridPose =
118 generateNewPose(poses.back(), nextMotionStep, transNoise, rotNoise);
119
120 // check whether we will walk outside the boundaries in the next iteration
121 SE2 nextStepFinalPose = nextGridPose.truePose * maxStepTransf;
122 if (fabs(nextStepFinalPose.translation().x()) >= bound[0] ||
123 fabs(nextStepFinalPose.translation().y()) >= bound[1]) {
124 // cerr << "b";
125 // will be outside boundaries using this
126 for (int i = 0; i < MO_NUM_ELEMS; ++i) {
127 nextMotionStep = getMotion(i, stepLen);
128 nextGridPose =
129 generateNewPose(poses.back(), nextMotionStep, transNoise, rotNoise);
130 nextStepFinalPose = nextGridPose.truePose * maxStepTransf;
131 if (fabs(nextStepFinalPose.translation().x()) < bound[0] &&
132 fabs(nextStepFinalPose.translation().y()) < bound[1])
133 break;
134 }
135 }
136
137 poses.push_back(nextGridPose);
138 }
139 cerr << "done." << endl;
140
141 // creating landmarks along the trajectory
142 cerr << "Simulator: Creating landmarks ... ";
143 LandmarkGrid grid;
144 for (PosesVector::const_iterator it = poses.begin(); it != poses.end();
145 ++it) {
146 int ccx = (int)round(it->truePose.translation().x());
147 int ccy = (int)round(it->truePose.translation().y());
148 for (int a = -landmarksRange; a <= landmarksRange; a++)
149 for (int b = -landmarksRange; b <= landmarksRange; b++) {
150 int cx = ccx + a;
151 int cy = ccy + b;
152 LandmarkPtrVector& landmarksForCell = grid[cx][cy];
153 if (landmarksForCell.size() == 0) {
154 for (int i = 0; i < landMarksPerSquareMeter; ++i) {
155 Landmark* l = new Landmark();
156 double offx, offy;
157 do {
158 offx = Sampler::uniformRand(-0.5 * stepLen, 0.5 * stepLen);
159 offy = Sampler::uniformRand(-0.5 * stepLen, 0.5 * stepLen);
160 } while (hypot_sqr(offx, offy) < 0.25 * 0.25);
161 l->truePose[0] = cx + offx;
162 l->truePose[1] = cy + offy;
163 landmarksForCell.push_back(l);
164 }
165 }
166 }
167 }
168 cerr << "done." << endl;
169
170 cerr << "Simulator: Simulating landmark observations for the poses ... ";
171 double maxSensorSqr = maxSensorRangeLandmarks * maxSensorRangeLandmarks;
172 int globalId = 0;
173 for (PosesVector::iterator it = poses.begin(); it != poses.end(); ++it) {
174 Simulator::GridPose& pv = *it;
175 int cx = (int)round(it->truePose.translation().x());
176 int cy = (int)round(it->truePose.translation().y());
177 int numGridCells = (int)(maxSensorRangeLandmarks) + 1;
178
179 pv.id = globalId++;
180 SE2 trueInv = pv.truePose.inverse();
181
182 for (int xx = cx - numGridCells; xx <= cx + numGridCells; ++xx)
183 for (int yy = cy - numGridCells; yy <= cy + numGridCells; ++yy) {
184 LandmarkPtrVector& landmarksForCell = grid[xx][yy];
185 if (landmarksForCell.size() == 0) continue;
186 for (size_t i = 0; i < landmarksForCell.size(); ++i) {
187 Landmark* l = landmarksForCell[i];
188 double dSqr =
189 hypot_sqr(pv.truePose.translation().x() - l->truePose.x(),
190 pv.truePose.translation().y() - l->truePose.y());
191 if (dSqr > maxSensorSqr) continue;
192 double obs = Sampler::uniformRand(0.0, 1.0);
193 if (obs > observationProb) // we do not see this one...
194 continue;
195 if (l->id < 0) l->id = globalId++;
196 if (l->seenBy.size() == 0) {
197 Vector2d trueObservation = trueInv * l->truePose;
198 Vector2d observation = trueObservation;
199 observation[0] += Sampler::gaussRand(0., landmarkNoise[0]);
200 observation[1] += Sampler::gaussRand(0., landmarkNoise[1]);
201 l->simulatedPose = pv.simulatorPose * observation;
202 }
203 l->seenBy.push_back(pv.id);
204 pv.landmarks.push_back(l);
205 }
206 }
207 }
208 cerr << "done." << endl;
209
210 // add the odometry measurements
211 _odometry.clear();
212 cerr << "Simulator: Adding odometry measurements ... ";
213 for (size_t i = 1; i < poses.size(); ++i) {
214 const GridPose& prev = poses[i - 1];
215 const GridPose& p = poses[i];
216
217 _odometry.push_back(GridEdge());
218 GridEdge& edge = _odometry.back();
219
220 edge.from = prev.id;
221 edge.to = p.id;
222 edge.trueTransf = prev.truePose.inverse() * p.truePose;
223 edge.simulatorTransf = prev.simulatorPose.inverse() * p.simulatorPose;
224 edge.information = information;
225 }
226 cerr << "done." << endl;
227
228 _landmarks.clear();
229 _landmarkObservations.clear();
230 // add the landmark observations
231 {
232 cerr << "Simulator: add landmark observations ... ";
233 Matrix2d covariance;
234 covariance.fill(0.);
235 covariance(0, 0) = landmarkNoise[0] * landmarkNoise[0];
236 covariance(1, 1) = landmarkNoise[1] * landmarkNoise[1];
237 Matrix2d information = covariance.inverse();
238
239 for (size_t i = 0; i < poses.size(); ++i) {
240 const GridPose& p = poses[i];
241 for (size_t j = 0; j < p.landmarks.size(); ++j) {
242 Landmark* l = p.landmarks[j];
243 if (l->seenBy.size() > 0 && l->seenBy[0] == p.id) {
244 landmarks.push_back(*l);
245 }
246 }
247 }
248
249 for (size_t i = 0; i < poses.size(); ++i) {
250 const GridPose& p = poses[i];
251 SE2 trueInv = (p.truePose * sensorOffset).inverse();
252 for (size_t j = 0; j < p.landmarks.size(); ++j) {
253 Landmark* l = p.landmarks[j];
254 Vector2d observation;
255 Vector2d trueObservation = trueInv * l->truePose;
256 observation = trueObservation;
257 if (l->seenBy.size() > 0 &&
258 l->seenBy[0] ==
259 p.id) { // write the initial position of the landmark
260 observation =
261 (p.simulatorPose * sensorOffset).inverse() * l->simulatedPose;
262 } else {
263 // create observation for the LANDMARK using the true positions
264 observation[0] += Sampler::gaussRand(0., landmarkNoise[0]);
265 observation[1] += Sampler::gaussRand(0., landmarkNoise[1]);
266 }
267
268 _landmarkObservations.push_back(LandmarkEdge());
269 LandmarkEdge& le = _landmarkObservations.back();
270
271 le.from = p.id;
272 le.to = l->id;
273 le.trueMeas = trueObservation;
274 le.simulatorMeas = observation;
275 le.information = information;
276 }
277 }
278 cerr << "done." << endl;
279 }
280
281 // cleaning up
282 for (LandmarkGrid::iterator it = grid.begin(); it != grid.end(); ++it) {
283 for (std::map<int, Simulator::LandmarkPtrVector>::iterator itt =
284 it->second.begin();
285 itt != it->second.end(); ++itt) {
287 for (size_t i = 0; i < landmarks.size(); ++i) delete landmarks[i];
288 }
289 }
290}
static double uniformRand(double lowerBndr, double upperBndr)
Definition sampler.h:102
const PosesVector & poses() const
Definition simulator.h:98
GridPose generateNewPose(const GridPose &prev, const SE2 &trueMotion, const Eigen::Vector2d &transNoise, double rotNoise)
std::vector< Landmark * > LandmarkPtrVector
Definition simulator.h:55
std::vector< GridPose > PosesVector
Definition simulator.h:67
const LandmarkVector & landmarks() const
Definition simulator.h:99
std::vector< Landmark > LandmarkVector
Definition simulator.h:54
SE2 getMotion(int motionDirection, double stepLen)
#define DEG2RAD(x)
Definition macros.h:31
std::map< int, std::map< int, Simulator::LandmarkPtrVector > > LandmarkGrid
Definition simulator.cpp:48
T hypot_sqr(T x, T y)
Definition misc.h:84

References _landmarkObservations, _landmarks, _odometry, _poses, DEG2RAD, g2o::tutorial::Simulator::GridEdge::from, g2o::tutorial::Simulator::LandmarkEdge::from, g2o::Sampler::gaussRand(), generateNewPose(), getMotion(), g2o::hypot_sqr(), g2o::tutorial::Simulator::Landmark::id, g2o::tutorial::Simulator::GridPose::id, g2o::tutorial::Simulator::GridEdge::information, g2o::tutorial::Simulator::LandmarkEdge::information, g2o::tutorial::SE2::inverse(), g2o::tutorial::Simulator::GridPose::landmarks, landmarks(), poses(), g2o::tutorial::Simulator::Landmark::seenBy, g2o::tutorial::Simulator::Landmark::simulatedPose, g2o::tutorial::Simulator::LandmarkEdge::simulatorMeas, g2o::tutorial::Simulator::GridPose::simulatorPose, g2o::tutorial::Simulator::GridEdge::simulatorTransf, g2o::tutorial::Simulator::GridEdge::to, g2o::tutorial::Simulator::LandmarkEdge::to, g2o::tutorial::SE2::translation(), g2o::tutorial::Simulator::LandmarkEdge::trueMeas, g2o::tutorial::Simulator::Landmark::truePose, g2o::tutorial::Simulator::GridPose::truePose, g2o::tutorial::Simulator::GridEdge::trueTransf, and g2o::Sampler::uniformRand().

Member Data Documentation

◆ _landmarkObservations

LandmarkEdgeVector g2o::tutorial::Simulator::_landmarkObservations
protected

Definition at line 109 of file simulator.h.

Referenced by simulate().

◆ _landmarks

LandmarkVector g2o::tutorial::Simulator::_landmarks
protected

Definition at line 107 of file simulator.h.

Referenced by simulate().

◆ _odometry

GridEdgeVector g2o::tutorial::Simulator::_odometry
protected

Definition at line 108 of file simulator.h.

Referenced by simulate().

◆ _poses

PosesVector g2o::tutorial::Simulator::_poses
protected

Definition at line 106 of file simulator.h.

Referenced by simulate().


The documentation for this class was generated from the following files: