pfuclt_particles.h
Go to the documentation of this file.
1 #ifndef PARTICLES_H
2 #define PARTICLES_H
3 
4 #include <ros/ros.h>
6 
7 #include <vector>
8 #include <algorithm>
9 #include <iostream>
10 #include <sstream>
11 #include <boost/random.hpp>
12 #include <boost/thread/mutex.hpp>
13 #include <eigen3/Eigen/Core>
14 #include <eigen3/Eigen/Geometry>
15 
16 #include <pfuclt_omni_dataset/particle.h>
17 #include <pfuclt_omni_dataset/particles.h>
18 
19 #include <dynamic_reconfigure/server.h>
20 #include <pfuclt_omni_dataset/DynamicConfig.h>
21 
22 #define NUM_ALPHAS 4
23 
24 // ideally later this will be a parameter, when it makes sense to
25 #define STATES_PER_TARGET 3
26 
27 // offsets
28 #define O_X (0)
29 #define O_Y (1)
30 #define O_THETA (2)
31 //#define O_TARGET (nRobots_ * nStatesPerRobot_)
32 #define O_TX (0)
33 #define O_TY (1)
34 #define O_TZ (2)
35 //#define O_WEIGHT (nSubParticleSets_ - 1)
36 
37 // target motion model and estimator
38 #define TARGET_RAND_MEAN 0
39 #define TARGET_RAND_STDDEV_LOST 500.0
40 
41 // concerning time
42 #define TARGET_ITERATION_TIME_DEFAULT 0.0333
43 #define TARGET_ITERATION_TIME_MAX (1)
44 
45 // others
46 #define MIN_WEIGHTSUM 1e-10
47 
48 //#define MORE_DEBUG true
49 
50 namespace pfuclt_omni_dataset
51 {
52 typedef float pdata_t;
53 
54 typedef double (*estimatorFunc)(const std::vector<double>&,
55  const std::vector<double>&);
56 
57 typedef struct odometry_s
58 {
59  double x, y, theta;
60 } Odometry;
61 
62 typedef struct landmarkObs_s
63 {
64  bool found;
65  double x, y;
66  double d, phi;
67  double covDD, covPP, covXX, covYY;
68  landmarkObs_s() { found = false; }
70 
71 typedef struct targetObs_s
72 {
73  bool found;
74  double x, y, z;
75  double d, phi, r;
76  double covDD, covPP, covXX, covYY;
77 
78  targetObs_s() { found = false; }
80 
81 // Apply concept of subparticles (the particle set for each dimension)
82 typedef std::vector<pdata_t> subparticles_t;
83 typedef std::vector<subparticles_t> particles_t;
84 
85 // This will be the generator use for randomizing
86 typedef boost::random::mt19937 RNGType;
87 
89 {
90 private:
91  boost::mutex mutex_;
92  dynamic_reconfigure::Server<DynamicConfig>
94 
95 protected:
97  {
103  std::vector<std::vector<float> > alpha;
104 
105  dynamicVariables_s(ros::NodeHandle& nh, const uint nRobots);
106 
107  void fill_alpha(const uint robot, const std::string& str);
108 
109  } dynamicVariables_;
110 
115  struct State
116  {
118  uint nRobots;
119 
124  typedef struct robotState_s
125  {
126  std::vector<pdata_t> pose;
127  pdata_t conf;
128 
129  robotState_s(uint poseSize) : pose(poseSize, 0.0), conf(0.0) {}
130  } RobotState;
131  std::vector<RobotState> robots;
132 
138  {
139  std::vector<pdata_t> pos;
140  bool seen;
141 
143  : pos(STATES_PER_TARGET, 0.0), seen(false)
144  {
145  }
146  } target;
147 
151  State(const uint nStatesPerRobot, const uint nRobots)
152  : nStatesPerRobot(nStatesPerRobot), nRobots(nRobots)
153  {
154  // Create and initialize the robots vector
155  for (uint r = 0; r < nRobots; ++r)
156  robots.push_back(robotState_s(nStatesPerRobot));
157  }
158  };
159 
160 public:
165  struct PFinitData
166  {
167  ros::NodeHandle& nh;
168  const uint mainRobotID, nTargets, statesPerRobot, nRobots, nLandmarks;
169  const std::vector<bool>& robotsUsed;
170  const std::vector<Landmark>& landmarksMap;
171 
188  PFinitData(ros::NodeHandle& nh, const uint mainRobotID, const uint nTargets,
189  const uint statesPerRobot, const uint nRobots,
190  const uint nLandmarks, const std::vector<bool>& robotsUsed,
191  const std::vector<Landmark>& landmarksMap)
192  : nh(nh), mainRobotID(mainRobotID), nTargets(nTargets),
193  statesPerRobot(statesPerRobot), nRobots(nRobots),
194  nLandmarks(nLandmarks), robotsUsed(robotsUsed),
195  landmarksMap(landmarksMap)
196  {
197  }
198  };
199 
200 protected:
201  ros::NodeHandle& nh_;
203  const uint mainRobotID_;
204  const uint nTargets_;
205  const uint nStatesPerRobot_;
206  const uint nRobots_;
207  const uint nSubParticleSets_;
208  const uint nLandmarks_;
209  particles_t particles_;
210  particles_t weightComponents_;
211  RNGType seed_;
213  const std::vector<Landmark>& landmarksMap_;
214  const std::vector<bool>& robotsUsed_;
215  std::vector<std::vector<LandmarkObservation> > bufLandmarkObservations_;
216  std::vector<TargetObservation> bufTargetObservations_;
218  ros::WallTime iterationEvalTime_;
219  ros::WallDuration deltaIteration_, maxDeltaIteration_;
220  ros::WallDuration durationSum;
222  struct State state_;
223  ros::Time latestObservationTime_, savedLatestObservationTime_;
225 
235  inline void copyParticle(particles_t& p_To, particles_t& p_From, uint i_To,
236  uint i_From)
237  {
238  copyParticle(p_To, p_From, i_To, i_From, 0, p_To.size() - 1);
239  }
240 
252  inline void copyParticle(particles_t& p_To, particles_t& p_From, uint i_To,
253  uint i_From, uint subFirst, uint subLast)
254  {
255  for (uint k = subFirst; k <= subLast; ++k)
256  p_To[k][i_To] = p_From[k][i_From];
257  }
258 
262  inline void resetWeights(pdata_t val)
263  {
264  particles_[O_WEIGHT].assign(particles_[O_WEIGHT].size(), val);
265  }
266 
275  void spreadTargetParticlesSphere(float particlesRatio, pdata_t center[3],
276  float radius);
277 
282  void predictTarget();
283 
287  void fuseRobots();
288 
292  void fuseTarget();
293 
298  void modifiedMultinomialResampler(uint startAt);
299 
303  void resample();
304 
308  void estimate();
309 
313  virtual void nextIteration() {}
314 
319  virtual void resize_particles(const uint n)
320  {
321  size_t old_size = particles_[0].size();
322 
323  // Resize weightComponents
324  for (uint r = 0; r < weightComponents_.size(); ++r)
325  weightComponents_[r].resize(n);
326 
327  // Resize particles
328  for (uint s = 0; s < particles_.size(); ++s)
329  particles_[s].resize(n);
330 
331  // If n is lower than old_size, the last particles are removed - the ones
332  // with the most weight are kept
333  // But if n is higher, it's better to resample
334  if (n > old_size)
335  resample();
336  }
337 
338 public:
339  boost::shared_ptr<std::ostringstream> iteration_oss;
340  uint O_TARGET, O_WEIGHT;
341 
346  void dynamicReconfigureCallback(pfuclt_omni_dataset::DynamicConfig&);
347 
353  ParticleFilter(struct PFinitData& data);
354 
361  void updateTargetIterationTime(ros::Time tRos)
362  {
363  targetIterationTime_.updateTime(tRos);
364 
365  if (fabs(targetIterationTime_.diff) > TARGET_ITERATION_TIME_MAX)
366  {
367  // Something is wrong, set to default iteration time
368  targetIterationTime_.diff = TARGET_ITERATION_TIME_DEFAULT;
369  }
370  ROS_DEBUG("Target tracking iteration time: %f", targetIterationTime_.diff);
371  }
372 
378  ParticleFilter* getPFReference() { return this; }
379 
383  void printWeights(std::string pre);
384 
389  void assign(const pdata_t value);
390 
396  void assign(const pdata_t value, const uint index);
397 
403  inline subparticles_t& operator[](int index) { return particles_[index]; }
404 
412  inline const subparticles_t& operator[](int index) const
413  {
414  return particles_[index];
415  }
416 
421  void init();
422 
433  void init(const std::vector<double>& customRandInit,
434  const std::vector<double>& customPosInit);
435 
444  void predict(const uint robotNumber, const Odometry odom,
445  const ros::Time stamp);
446 
452  bool isInitialized() { return initialized_; }
453 
458  std::size_t size() { return nSubParticleSets_; }
459 
468  inline void saveLandmarkObservation(const uint robotNumber,
469  const uint landmarkNumber,
470  const LandmarkObservation obs,
471  ros::Time stamp)
472  {
473  bufLandmarkObservations_[robotNumber][landmarkNumber] = obs;
474  latestObservationTime_ = stamp;
475  }
476 
482  inline void saveLandmarkObservation(const uint robotNumber,
483  const uint landmarkNumber,
484  const bool found)
485  {
486  bufLandmarkObservations_[robotNumber][landmarkNumber].found = found;
487  }
488 
495  void saveAllLandmarkMeasurementsDone(const uint robotNumber);
496 
503  inline void saveTargetObservation(const uint robotNumber,
504  const TargetObservation obs,
505  ros::Time stamp)
506  {
507  bufTargetObservations_[robotNumber] = obs;
508 
509  // If previously target not seen and now is found
510  if (obs.found && !state_.target.seen)
511  {
512  // Update to target seen
513  state_.target.seen = true;
514 
515  // Observation to global frame
516  const ParticleFilter::State::RobotState& rs = state_.robots[robotNumber];
517  pdata_t ballGlobal[3];
518  ballGlobal[O_TX] = rs.pose[O_X] + obs.x * cos(rs.pose[O_THETA]) -
519  obs.y * sin(rs.pose[O_THETA]);
520  ballGlobal[O_TY] = rs.pose[O_Y] + obs.x * sin(rs.pose[O_THETA]) +
521  obs.y * cos(rs.pose[O_THETA]);
522  ballGlobal[O_TZ] = obs.z;
523 
524  // Spread 50% of particles around ballGlobal in a sphere with 1.0 meter
525  // radius
526  spreadTargetParticlesSphere(0.5, ballGlobal, 1.0);
527  }
528  }
529 
535  inline void saveTargetObservation(const uint robotNumber, const bool found)
536  {
537  bufTargetObservations_[robotNumber].found = found;
538  }
539 
546  void saveAllTargetMeasurementsDone(const uint robotNumber);
547 };
548 
549 // end of namespace pfuclt_omni_dataset
550 }
551 #endif // PARTICLES_H
dynamic_reconfigure::Server< DynamicConfig > dynamicServer_
void resetWeights(pdata_t val)
resetWeights - assign the value val to all particle weights
const std::vector< Landmark > & landmarksMap
#define O_X
#define TARGET_ITERATION_TIME_DEFAULT
void updateTargetIterationTime(ros::Time tRos)
updateTargetIterationTime - the main robot should call this method after the target callback ...
std::vector< pdata_t > subparticles_t
#define O_TX
#define STATES_PER_TARGET
std::vector< TargetObservation > bufTargetObservations_
double(* estimatorFunc)(const std::vector< double > &, const std::vector< double > &)
std::size_t size()
size - interface to the size of the particle filter
struct pfuclt_omni_dataset::landmarkObs_s LandmarkObservation
bool isInitialized()
isInitialized - simple interface to access private member initialized_
#define O_Y
The targetState_s struct - saves information on the belief of the target&#39;s state. ...
State(const uint nStatesPerRobot, const uint nRobots)
State - constructor.
const subparticles_t & operator[](int index) const
operator [] - const version of the array subscripting access, when using it on const intantiations of...
The robotState_s struct - saves information on the belief of a robot&#39;s state.
boost::random::mt19937 RNGType
#define O_TY
The state_s struct - defines a structure to hold state information for the particle filter class...
void saveTargetObservation(const uint robotNumber, const TargetObservation obs, ros::Time stamp)
saveTargetObservation - saves the target observation to a buffer of observations
subparticles_t & operator[](int index)
operator [] - array subscripting access to the private particle set
void copyParticle(particles_t &p_To, particles_t &p_From, uint i_To, uint i_From, uint subFirst, uint subLast)
copyParticle - copies some subparticle sets of a particle from one particle set to another ...
std::vector< std::vector< LandmarkObservation > > bufLandmarkObservations_
#define TARGET_ITERATION_TIME_MAX
ParticleFilter * getPFReference()
getPFReference - retrieve a reference to this object - to be overloaded by deriving classes so that t...
The PFinitData struct - provides encapsulation to the initial data necessary to construct a ParticleF...
void saveLandmarkObservation(const uint robotNumber, const uint landmarkNumber, const bool found)
saveLandmarkObservation - change the measurement buffer state
#define O_THETA
void saveLandmarkObservation(const uint robotNumber, const uint landmarkNumber, const LandmarkObservation obs, ros::Time stamp)
saveLandmarkObservation - saves the landmark observation to a buffer of observations ...
const std::vector< bool > & robotsUsed_
struct pfuclt_omni_dataset::odometry_s Odometry
boost::shared_ptr< std::ostringstream > iteration_oss
virtual void nextIteration()
nextIteration - perform final steps before next iteration
#define O_TZ
The timeEval_s struct - takes care of time difference evaluation through the ros::Time methods...
Definition: pfuclt_aux.h:160
struct pfuclt_omni_dataset::targetObs_s TargetObservation
PFinitData(ros::NodeHandle &nh, const uint mainRobotID, const uint nTargets, const uint statesPerRobot, const uint nRobots, const uint nLandmarks, const std::vector< bool > &robotsUsed, const std::vector< Landmark > &landmarksMap)
PFinitData.
std::vector< subparticles_t > particles_t
virtual void resize_particles(const uint n)
resize_particles - change to a different number of particles
void saveTargetObservation(const uint robotNumber, const bool found)
saveTargetObservation - change the measurement buffer state
double updateTime(ros::Time t)
updateTime - adds the newest time available to the struct and returns the time difference ...
Definition: pfuclt_aux.h:178
void copyParticle(particles_t &p_To, particles_t &p_From, uint i_To, uint i_From)
copyParticle - copies a whole particle from one particle set to another
const std::vector< Landmark > & landmarksMap_


pfuclt_omni_dataset
Author(s):
autogenerated on Tue Jul 4 2017 19:38:38