00001
00014 #ifndef SIMUOBJECTS_HPP_
00015 #define SIMUOBJECTS_HPP_
00016
00017 #include "kernel/dataLog.hpp"
00018 #include "jmath/jblas.hpp"
00019
00020 namespace jafar {
00021 namespace rtslam {
00022 namespace simu {
00023
00024 class AdhocSimulator;
00025
00026 class Object
00027 {
00028 public:
00029 size_t id;
00030 };
00031
00032 class MapObject: public simu::Object
00033 {
00034 private:
00035 size_t size;
00036 public:
00037 MapObject(size_t size): size(size) {}
00038 virtual jblas::vec getPose(double t) const = 0;
00039 virtual bool hasEnded(double t) const { return true; }
00040
00041 };
00042
00043 typedef ublas::bounded_vector<double,12> vec12;
00044 struct Waypoint
00045 {
00046 double t;
00047 vec12 pose;
00048 };
00049 typedef std::vector<Waypoint> Trajectory;
00050
00051 class MobileObject: public simu::MapObject, public kernel::DataLoggable
00052 {
00053 private:
00054 mutable double _t;
00055 Trajectory traj;
00056 void getWaypointsIndexes(double t, int &i_before, int &i_after) const
00057 {
00058 int n = traj.size();
00059 if (n == 0) JFR_ERROR(RtslamException, RtslamException::SIMU_ERROR, "simu trajectory is empty");
00060 if (t <= traj[0].t) { i_before = i_after = 0; return; }
00061 if (t >= traj[n-1].t) { i_before = i_after = n-1; return; }
00062
00063
00064 int a,b;
00065 for (a = 0, b = n-1; b-a > 1; )
00066 {
00067 int i = (a+b)/2;
00068 if (traj[i].t < t) a = i; else b = i;
00069 }
00070 i_before = a;
00071 i_after = b;
00072 }
00073
00074 public:
00075 MobileObject(size_t size): MapObject(size) {}
00076 void clear() { traj.clear(); }
00081 bool hasEnded(double t) const { if (traj.size() == 0) return true; return (t > traj.back().t); }
00082 void addWaypoint(double x, double y, double z, double yaw, double pitch, double roll,
00083 double vx, double vy, double vz, double vyaw, double vpitch, double vroll)
00084 {
00085 double pose_[12] = {x, y, z, yaw, pitch, roll, vx, vy, vz, vyaw, vpitch, vroll};
00086 jblas::vec pose = createVector<12>(pose_);
00087 addWaypoint(pose);
00088 }
00089
00090 bool addWaypoint(jblas::vec pose)
00091 {
00092 JFR_ASSERT(pose.size() == 12, "pose must be size 12 (pos,ori,vpos,vori)");
00093 Waypoint p; p.pose.clear();
00094 p.pose = pose;
00095 if (traj.size() == 0)
00096 {
00097 p.t = 0.;
00098 } else
00099 {
00100 Waypoint &lastp = traj.back();
00101 p.t = 0.;
00102
00103 for(int i = 0; i < 6; ++i)
00104 {
00105 double avg_vel = (p.pose(i+6) + lastp.pose(i+6)) / 2;
00106 double t = (p.pose(i) - lastp.pose(i)) / avg_vel;
00107 if (t > p.t) p.t = t;
00108 }
00109
00110 for(int i = 0; i < 6; ++i)
00111 {
00112 double avg_vel = (p.pose(i) - lastp.pose(i)) / p.t;
00113 p.pose(i+6) = 2*avg_vel - lastp.pose(i+6);
00114 }
00115
00116 p.t += lastp.t;
00117 }
00118 traj.push_back(p);
00119 return true;
00120 }
00121
00122 jblas::vec getPose(double t) const
00123 {
00124 _t = t;
00125 int a, b;
00126 getWaypointsIndexes(t,a,b);
00127 if (a == b) return ublas::subrange(traj[b].pose,0,6);
00128
00129 jblas::vec p1 = ublas::subrange(traj[a].pose,0,6 );
00130 jblas::vec v1 = ublas::subrange(traj[a].pose,6,12);
00131 jblas::vec v2 = ublas::subrange(traj[b].pose,6,12);
00132 double t1 = traj[a].t, t2 = traj[b].t;
00133
00134 return p1 + (t2*v1-t1*v2)*((t-t1)/(t2-t1)) + 0.5*(v2-v1)*((t*t-t1*t1)/(t2-t1));
00135 }
00136 jblas::vec getSpeed(double t) const
00137 {
00138 _t = t;
00139 int a, b;
00140 getWaypointsIndexes(t,a,b);
00141 if (a == b) return ublas::subrange(traj[b].pose,6,12);
00142
00143 double tp = (t - traj[a].t) / (traj[b].t - traj[a].t);
00144 return (1-tp) * ublas::subrange(traj[a].pose,6,12) + tp * ublas::subrange(traj[b].pose,6,12);
00145 }
00146 jblas::vec getAcc(double t) const
00147 {
00148 _t = t;
00149 int a, b;
00150 getWaypointsIndexes(t,a,b);
00151 if (a == b) return jblas::zero_vec(6);
00152
00153 double dt = traj[b].t - traj[a].t;
00154 return (ublas::subrange(traj[b].pose,6,12) - ublas::subrange(traj[a].pose,6,12)) / dt;
00155 }
00156
00157
00158 virtual void writeLogHeader(kernel::DataLogger& log) const
00159 {
00160 log.writeLegendTokens("simu_x simu_y simu_z");
00161 log.writeLegendTokens("simu_yaw simu_pitch simu_roll");
00162 }
00163 virtual void writeLogData(kernel::DataLogger& log) const
00164 {
00165 jblas::vec pose = getPose(_t);
00166 for(int i = 0 ; i < 6 ; ++i) log.writeData(pose(i));
00167 }
00168
00169 };
00170
00171
00172 class Sensor: public simu::MapObject
00173 {
00174 private:
00175 jblas::vec pose;
00176
00177
00178 std::map<LandmarkAbstract::geometry_t, ObservationModelAbstract*> obsModels;
00179
00180 public:
00181 Sensor(size_t id, jblas::vec pose, sensor_ptr_t slamSensor): MapObject(pose.size()), pose(pose) { this->id = id; }
00182 ~Sensor()
00183 {
00184 for(std::map<LandmarkAbstract::geometry_t, ObservationModelAbstract*>::iterator it = obsModels.begin(); it != obsModels.end(); ++it) delete it->second;
00185 }
00186
00187 void addObservationModel(LandmarkAbstract::geometry_t lmkType, ObservationModelAbstract *obsModel)
00188 { obsModels[lmkType] = obsModel; }
00189 jblas::vec getPose(double t) const { return pose; }
00190
00191 friend class AdhocSimulator;
00192 };
00193
00194 class Robot: public simu::MobileObject
00195 {
00196 private:
00197 std::map<size_t,simu::Sensor*> sensors;
00198 public:
00199 Robot(size_t id, size_t size): MobileObject(size) { this->id = id; }
00200 ~Robot()
00201 {
00202 for(std::map<size_t,simu::Sensor*>::iterator it = sensors.begin(); it != sensors.end(); ++it) delete it->second;
00203 }
00204 void addSensor(simu::Sensor *sensor) { sensors[sensor->id] = sensor; }
00205 jblas::vec getSensorPose(size_t senId, double t) const
00206 {
00207 std::map<size_t,simu::Sensor*>::const_iterator itSen = sensors.find(senId);
00208 if (itSen == sensors.end()) return jblas::vec();
00209 return itSen->second->getPose(t);
00210 }
00211
00212 friend class AdhocSimulator;
00213 };
00214
00215 class Landmark: public simu::MapObject
00216 {
00217 private:
00218 jblas::vec pose;
00219 public:
00220 LandmarkAbstract::geometry_t type;
00221 public:
00222 Landmark(LandmarkAbstract::geometry_t type, jblas::vec pose): MapObject(pose.size()), pose(pose),type(type) {}
00223 jblas::vec getPose(double t) const { return pose; }
00224
00225 };
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 }}}
00240
00241
00242 #endif
00243