Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
robotAbstract.hpp
Go to the documentation of this file.
00001 
00010 #ifndef __RobotAbstract_H__
00011 #define __RobotAbstract_H__
00012 
00013 /* --------------------------------------------------------------------- */
00014 /* --- INCLUDE --------------------------------------------------------- */
00015 /* --------------------------------------------------------------------- */
00016 
00017 #include "kernel/jafarDebug.hpp"
00018 #include "kernel/IdFactory.hpp"
00019 #include "kernel/dataLog.hpp"
00020 #include "kernel/timingTools.hpp"
00021 #include "jmath/jblas.hpp"
00022 #include "jmath/indirectArray.hpp"
00023 
00024 #include "rtslam/rtSlam.hpp"
00025 #include "rtslam/gaussian.hpp"
00026 #include "rtslam/mapObject.hpp"
00027 #include "rtslam/perturbation.hpp"
00028 #include "rtslam/quatTools.hpp"
00029 // include parents
00030 #include "rtslam/mapAbstract.hpp"
00031 #include "rtslam/mapObject.hpp"
00032 #include "rtslam/parents.hpp"
00033 
00034 #include "rtslam/hardwareSensorAbstract.hpp"
00035 
00036 namespace jafar {
00037   namespace rtslam {
00038 
00039 
00040     //  Forward declarations of children
00041     class SensorAbstract;
00042 
00043     class RobotQuantity
00044     {
00045       public:
00055         enum Quantity { qPos, qOriQuat, qAbsVel, qAngVel, qAbsAcc, qAngAcc, qAbsJerk, qAngJerk, qG, qNormG, qNQuantity };
00056         static const int QuantityDataSizes[qNQuantity];
00057         typedef std::vector<Quantity> QuantityList;
00058       protected:
00059         size_t state_size;
00060         int quantities[qNQuantity];
00061       public:
00062         RobotQuantity()
00063           { clearQuantities(); }
00064         RobotQuantity(QuantityList quants)
00065           { clearQuantities(); for(QuantityList::iterator it = quants.begin(); it != quants.end(); ++it) registerRobotQuantity(*it); }
00066         RobotQuantity(RobotQuantity const & robQuant, QuantityList quants)
00067           { clearQuantities(); for(QuantityList::iterator it = quants.begin(); it != quants.end(); ++it) quantities[*it] = robQuant.quantities[*it]; }
00068 
00070         virtual bool registerRobotQuantity(Quantity quantity)
00071           { if (quantities[quantity] < 0) { quantities[quantity] = state_size; state_size += QuantityDataSizes[quantity]; return false; } else return true; }
00073         virtual ublas::range allocateSensorQuantity(size_t size)
00074           { size_t pos = state_size; state_size += size; return ublas::range(pos, state_size); }
00076         virtual void clearQuantities()
00077           { for(int i = 0; i < qNQuantity; ++i) quantities[i] = -1; state_size = 0; }
00078 
00079         inline bool hasQuantity(Quantity quantity)
00080           { return (quantities[quantity] >= 0); }
00081         inline ublas::range getQuantity(Quantity quantity)
00082           { return hasQuantity(quantity) ? ublas::range(quantities[quantity], quantities[quantity]+QuantityDataSizes[quantity]) : ublas::range(0,0); }
00083         inline jblas::ind_array getQuantities()
00084           { jblas::ind_array ia; for(int i = 0; i < qNQuantity; ++i) if (hasQuantity((Quantity)i)) ia = ia_union(ia, ia_set(getQuantity((Quantity)i))); return ia; }
00085     };
00086 
00087 
00093     class RobotAbstract: public MapObject,
00094                          public ChildOf<MapAbstract>,
00095                          public boost::enable_shared_from_this<RobotAbstract>,
00096                          public ParentOf<SensorAbstract>,
00097                          public kernel::DataLoggable,
00098                          public RobotQuantity {
00099 
00100         friend ostream& operator <<(ostream & s, RobotAbstract const & rob);
00101 
00102       protected:
00103         bool constructed;
00104         static IdFactory robotIds;
00105       public:
00107         virtual bool registerRobotQuantity(Quantity quantity)
00108         {
00109           if (!RobotQuantity::registerRobotQuantity(quantity))
00110           {
00111             if (constructed) construct(mapPtr(), state_size, control.size(), perturbation.size());
00112             return false;
00113           } else
00114             return true;
00115         }
00116         virtual ublas::range allocateSensorQuantity(size_t size)
00117         {
00118           ublas::range r = RobotQuantity::allocateSensorQuantity(size);
00119           if (constructed) construct(mapPtr(), state_size, control.size(), perturbation.size());
00120           return r;
00121         }
00122 
00123         enum type_enum {
00124           ODOMETRY, CONSTANT_VELOCITY, CONSTANT_MOTION_MODEL, INERTIAL, CENTERED_CONSTANT_VELOCITY
00125         };
00126         type_enum type;
00127 
00128         sensor_ptr_t last_updated;
00129 
00130         // define the function linkToParentMap().
00131         ENABLE_LINK_TO_PARENT(MapAbstract,Map,RobotAbstract)
00132         ;
00133         // define the functions mapPtr() and map().
00134         ENABLE_ACCESS_TO_PARENT(MapAbstract,map)
00135         ;
00136         // define the type SensorList, and the function sensorList().
00137         ENABLE_ACCESS_TO_CHILDREN(SensorAbstract,Sensor,sensor);
00138 
00139         hardware::hardware_sensorprop_ptr_t hardwareEstimatorPtr;
00140         history_manager_ptr_t historyManager;
00141 
00142         RobotAbstract(const map_ptr_t & _mapPtr);
00143 
00151         void construct(const map_ptr_t & _mapPtr, const size_t _size_state, const size_t _size_control, const size_t _size_pert);
00152 
00153         // Mandatory virtual destructor.
00154         virtual ~RobotAbstract() {
00155         }
00156 
00157         void setPoseStd(double x, double y, double z,
00158           double roll, double pitch, double yaw,
00159           double xStd, double yStd, double zStd,
00160           double rollStd, double pitchStd, double yawStd,
00161           bool degrees = false);
00162         void setPositionStd(double x, double y, double z,
00163           double xStd, double yStd, double zStd);
00164         void setOrientationStd(double roll, double pitch, double yaw,
00165           double rollStd, double pitchStd, double yawStd,
00166           bool degrees = false);
00167 
00168         
00169         virtual std::string categoryName() const {
00170           return "ROBOT";
00171         }
00172 
00173 
00174         void setId(){id(robotIds.getId());}
00175 
00176         Gaussian pose; 
00177         vec control; 
00178         Perturbation perturbation; 
00179 
00194         bool constantPerturbation;
00195         kernel::Timestamp self_time; 
00196         double dt_or_dx; 
00197         jblas::mat controls;
00198 
00199         jblas::mat XNEW_x; 
00200         jblas::mat XNEW_pert; 
00201         jblas::sym_mat Q; 
00202         
00207         void setRobotPose(jblas::vec6 const & pose_euler, bool degrees = false);
00208         jblas::vec robot_pose; 
00209 
00213         void setInitialPose(double x, double y, double z,
00214           double roll, double pitch, double yaw,
00215           double xStd, double yStd, double zStd,
00216           double rollStd, double pitchStd, double yawStd,
00217           bool degrees = false);
00224         void setOrigin(double x, double y, double z)
00225         {
00226           start_pos_abs(0) = x;
00227           start_pos_abs(1) = y;
00228           start_pos_abs(2) = z;
00229           start_pos_abs += start_pos_export;
00230           is_start_pos_abs_init = true;
00231         }
00232 
00233         jblas::vec start_pos_export; 
00234         jblas::vec start_pos_abs; 
00235         bool is_start_pos_abs_init; 
00236 
00239         void setInitialOrientation(double roll, double pitch, double yaw,
00240           double rollStd, double pitchStd, double yawStd,
00241           bool degrees = false);
00246         void getCurrentPose(double time, jblas::vec & x, jblas::sym_mat & P);
00250         template<class VEC, class SYM_MAT>
00251         void slamPoseToRobotPose(VEC & slam_x, SYM_MAT & slam_P, jblas::vec & robot_x, jblas::sym_mat & robot_P) const
00252         {
00253           // normalize quat
00254           jblas::vec4 q = ublas::subrange(slam_x, 3, 7);
00255           jblas::mat Q_q(4,4), FQ_fq(7,7); FQ_fq.clear();
00256           ublasExtra::normalizeJac(q, Q_q);
00257           ublas::subrange(FQ_fq, 0,3, 0,3) = jblas::identity_mat(3);
00258           ublas::subrange(FQ_fq, 3,7, 3,7) = Q_q;
00259           slam_P = ublasExtra::prod_JPJt(slam_P, FQ_fq);
00260           ublasExtra::normalize(q);
00261           ublas::subrange(slam_x, 3, 7) = q;
00262 
00263           // convert mean
00264           jblas::vec7 quat_pose = quaternion::composeFrames(slam_x, robot_pose);
00265           jblas::vec6 euler_pose;
00266           ublas::subrange(euler_pose, 0,3) = ublas::subrange(quat_pose, 0,3) + start_pos_export;
00267           mat E_q(3, 4);
00268           jblas::vec3 euler_ori;
00269           quaternion::q2e(ublas::subrange(quat_pose, 3, 7), euler_ori, E_q);
00270           ublas::subrange(euler_pose, 3,6) = euler_ori;
00271 
00272           // convert cov
00273           mat FE_fq(6,7); FE_fq.clear();
00274           ublas::subrange(FE_fq,0,3,0,3) = identity_mat(3);
00275           ublas::subrange(FE_fq, 3,6,3,7) = E_q;
00276 
00277           jblas::mat Q_s(7,7);
00278           quaternion::composeFrames_by_dglobal(slam_x, robot_pose, Q_s);
00279 
00280           mat FE_s = ublas::prod(FE_fq, Q_s);
00281 
00282           robot_x = euler_pose;
00283           robot_P = prod_JPJt(slam_P, FE_s);
00284         }
00285 
00286 
00287         boost::mutex mutex_extrapol;
00288         bool extrapol_up_to_date;
00289         double self_time_extrapol, self_time_extrapol_init, self_time_extrapol_inc;
00290         jblas::vec state_extrapol_x, state_extrapol_x_init, state_extrapol_x_inc;
00291         jblas::sym_mat state_extrapol_P, state_extrapol_P_init, state_extrapol_P_inc;
00292         vec control_extrapol;
00293         Perturbation perturbation_extrapol;
00294         double dt_or_dx_extrapol;
00295         jblas::mat controls_extrapol;
00296         jblas::mat XNEW_x_extrapol;
00297         jblas::mat XNEW_pert_extrapol;
00298         jblas::sym_mat Q_extrapol;
00299 
00300 
00301         virtual size_t mySize() = 0;
00302         virtual size_t mySize_control() = 0;
00303         virtual size_t mySize_perturbation() = 0;
00304         static size_t size_control() {
00305           return 0;
00306         }
00307         static size_t size_perturbation() {
00308           return 0;
00309         }
00310         void set_control(const vec & c) {
00311           JFR_ASSERT(c.size() == mySize_control(), "RobotAbstract::set_control(vec&, double): Sizes mismatch");
00312           control = c;
00313         }
00314         void set_perturbation(const Perturbation & _pert) {
00315           perturbation = _pert;
00316         }
00317 
00318         void setHardwareEstimator(hardware::hardware_sensorprop_ptr_t hardwareEstimatorPtr_)
00319         {
00320           hardwareEstimatorPtr = hardwareEstimatorPtr_;
00321         }
00322 
00323 
00327         inline void init(const vec & _u, const vec & _U) {
00328           JFR_ASSERT(_u.size() >= control.size(), "robotAbstract.hpp: init: wrong control size.");
00329           control = ublas::subrange(_u, 0, control.size());
00330           vec x = state.x();
00331           vec xnew(x.size());
00332 
00333           init_func(x, control, _U, xnew);
00334           state.x() = xnew;
00335         }
00336         
00337         inline void init(const vec & _u) {
00338           JFR_ASSERT(_u.size() >= control.size(), "robotAbstract.hpp: init: wrong control size.");
00339           control = ublas::subrange(_u, 0, control.size());
00340           vec x = state.x();
00341           vec xnew(x.size());
00342 
00343           init_func(x, control, xnew);
00344           state.x() = xnew;
00345         }
00346 
00351         void move();
00352 
00357         //template<class V>
00358         inline void move(const vec & _u) {
00359           JFR_ASSERT(_u.size() >= control.size(), "robotAbstract.hpp: move: wrong control size.");
00360           control = ublas::subrange(_u, 0, control.size());
00361           move();
00362         }
00363 
00364         bool computeControls(double time1, double time2, jblas::mat & controls, bool release) const;
00365 
00366         virtual bool move(double time);
00367 
00372         void move_extrapolate();
00373         void move_extrapolate(double time);
00374         void reinit_extrapolate();
00378         void move_fake(double time);
00379 
00388         void computeStatePerturbation();
00389         void computeStatePerturbation_extrapol();
00390 
00391         void applyConstraints()
00392         {
00393           // TODO should also constrain sensors pose quaternions
00394           ublas::range iaOriQuat = getQuantity(qOriQuat);
00395           jblas::sym_mat Q(4,4); Q.clear();
00396           jblas::mat QN_q(4,4);
00397           jblas::vec q = ublas::project(state.x(), iaOriQuat);
00398           ublasExtra::normalizeJac(q, QN_q);
00399           ublas::project(state.x(), iaOriQuat) = ublasExtra::normalized(q);
00400           mapPtr()->filterPtr->predict(mapPtr()->ia_used_states(), QN_q, state.ia().compose(iaOriQuat), Q);
00401         }
00402 
00403         virtual void writeLogHeader(kernel::DataLogger& log) const;
00404         virtual void writeLogData(kernel::DataLogger& log) const;
00405 
00406         void stopDumping();
00407 
00408         void setHistoryManager(history_manager_ptr_t hm) { historyManager = hm; }
00409 
00410       protected:
00411 
00412 
00435         virtual void move_func(const vec & _x, const vec & _u, const vec& _n, const double _dt, vec & _xnew,
00436                                mat & _XNEW_x, mat & _XNEW_pert, unsigned tempSet = 0) const = 0;
00445         virtual void init_func(const vec & _x, const vec & _u, const vec & _U, vec & _xnew) {}
00446         virtual void init_func(const vec & _x, const vec & _u, vec & _xnew) {}
00447 
00448 
00449     };
00450 
00451   }
00452 }
00453 
00454 #endif // #ifndef __RobotAbstract_H__
00455 /*
00456  * Local variables:
00457  * mode: c++
00458  * indent-tabs-mode: t
00459  * tab-width: 2
00460  * c-basic-offset: 2
00461  * End:
00462  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:27 for Jafar by doxygen 1.7.6.1
LAAS-CNRS