Blender  V2.59
MovingFrame.cpp
Go to the documentation of this file.
00001 
00004 /* $Id: MovingFrame.cpp 35155 2011-02-25 11:45:16Z jesterking $
00005  * MovingFrame.cpp
00006  *
00007  *  Created on: Feb 10, 2009
00008  *      Author: benoitbolsee
00009  */
00010 
00011 #include "MovingFrame.hpp"
00012 #include <string.h>
00013 namespace iTaSC{
00014 
00015 static const unsigned int frameCacheSize = (sizeof(((Frame*)0)->p.data)+sizeof(((Frame*)0)->M.data))/sizeof(double);
00016 
00017 MovingFrame::MovingFrame(const Frame& frame):UncontrolledObject(),
00018         m_function(NULL), m_param(NULL), m_velocity(), m_poseCCh(-1), m_poseCTs(0)
00019 {
00020         m_internalPose = m_nextPose = frame;
00021         initialize(6, 1);
00022         e_matrix& Ju = m_JuArray[0];
00023         Ju = e_identity_matrix(6,6);
00024 }
00025 
00026 MovingFrame::~MovingFrame()
00027 {
00028 }
00029 
00030 void MovingFrame::finalize()
00031 {
00032         updateJacobian();
00033 }
00034 
00035 void MovingFrame::initCache(Cache *_cache)
00036 {
00037         m_cache = _cache;
00038         m_poseCCh = -1;
00039         if (m_cache) {
00040                 m_poseCCh = m_cache->addChannel(this,"pose",frameCacheSize*sizeof(double));
00041                 // don't store the initial pose, it's causing unnecessary large velocity on the first step
00042                 //pushInternalFrame(0);
00043         }
00044 }
00045 
00046 void MovingFrame::pushInternalFrame(CacheTS timestamp)
00047 {
00048         if (m_poseCCh >= 0) {
00049                 double buf[frameCacheSize];
00050                 memcpy(buf, m_internalPose.p.data, sizeof(m_internalPose.p.data));
00051                 memcpy(&buf[sizeof(m_internalPose.p.data)/sizeof(double)], m_internalPose.M.data, sizeof(m_internalPose.M.data));
00052 
00053                 m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, frameCacheSize, KDL::epsilon);
00054                 m_poseCTs = timestamp;
00055         }
00056 }
00057 
00058 // load pose just preceding timestamp
00059 // return false if no cache position was found
00060 bool MovingFrame::popInternalFrame(CacheTS timestamp)
00061 {
00062         if (m_poseCCh >= 0) {
00063                 char *item;
00064                 item = (char *)m_cache->getPreviousCacheItem(this, m_poseCCh, &timestamp);
00065                 if (item && m_poseCTs != timestamp) {
00066                         memcpy(m_internalPose.p.data, item, sizeof(m_internalPose.p.data));
00067                         item += sizeof(m_internalPose.p.data);
00068                         memcpy(m_internalPose.M.data, item, sizeof(m_internalPose.M.data));
00069                         m_poseCTs = timestamp;
00070                         // changing the starting pose, recompute the jacobian
00071                         updateJacobian();
00072                 }
00073                 return (item) ? true : false;
00074         }
00075         // in case of no cache, there is always a previous position
00076         return true;
00077 }
00078 
00079 bool MovingFrame::setFrame(const Frame& frame)
00080 {
00081         m_internalPose = m_nextPose = frame;
00082         return true;
00083 }
00084 
00085 bool MovingFrame::setCallback(MovingFrameCallback _function, void* _param)
00086 {
00087         m_function = _function;
00088         m_param = _param;
00089         return true;
00090 }
00091 
00092 void MovingFrame::updateCoordinates(const Timestamp& timestamp)
00093 {
00094         // don't compute the velocity during substepping, it is assumed constant.
00095         if (!timestamp.substep) {
00096                 bool cacheAvail = true;
00097                 if (!timestamp.reiterate) {
00098                         cacheAvail = popInternalFrame(timestamp.cacheTimestamp);
00099                         if (m_function)
00100                                 (*m_function)(timestamp, m_internalPose, m_nextPose, m_param);
00101                 }
00102                 // only compute velocity if we have a previous pose
00103                 if (cacheAvail && timestamp.interpolate) {
00104                         unsigned int iXu;
00105                         m_velocity = diff(m_internalPose, m_nextPose, timestamp.realTimestep);
00106                         for (iXu=0; iXu<6; iXu++)
00107                                 m_xudot(iXu) = m_velocity(iXu);
00108                 } else if (!timestamp.reiterate) {
00109                         // new position is forced, no velocity as we cannot interpolate
00110                         m_internalPose = m_nextPose;
00111                         m_velocity = Twist::Zero();
00112                         m_xudot = e_zero_vector(6);
00113                         // recompute the jacobian
00114                         updateJacobian();
00115                 }
00116         }
00117 }
00118 
00119 void MovingFrame::pushCache(const Timestamp& timestamp)
00120 {
00121         if (!timestamp.substep && timestamp.cache)
00122                 pushInternalFrame(timestamp.cacheTimestamp);
00123 }
00124 
00125 void MovingFrame::updateKinematics(const Timestamp& timestamp)
00126 {
00127         if (timestamp.interpolate) {
00128                 if (timestamp.substep) {
00129                         // during substepping, update the internal pose from velocity information
00130                         Twist localvel = m_internalPose.M.Inverse(m_velocity);
00131                         m_internalPose.Integrate(localvel, 1.0/timestamp.realTimestep);
00132                 } else {
00133                         m_internalPose = m_nextPose;
00134                 }
00135                 // m_internalPose is updated, recompute the jacobian
00136                 updateJacobian();
00137         }
00138         pushCache(timestamp);
00139 }
00140 
00141 void MovingFrame::updateJacobian()
00142 {
00143         Twist m_jac;
00144         e_matrix& Ju = m_JuArray[0];
00145 
00146     //Jacobian is always identity at position on the object, 
00147         //we ust change the reference to the world.
00148         //instead of going through complicated jacobian operation, implemented direct formula
00149         Ju(1,3) = m_internalPose.p.z();
00150         Ju(2,3) = -m_internalPose.p.y();
00151         Ju(0,4) = -m_internalPose.p.z();
00152         Ju(2,4) = m_internalPose.p.x();
00153         Ju(0,5) = m_internalPose.p.y();
00154         Ju(1,5) = -m_internalPose.p.x();
00155         // remember that this object has moved
00156         m_updated = true;
00157 }
00158 
00159 }