Revision: 20603 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20603 Author: ben2610 Date: 2009-06-03 17:17:52 +0200 (Wed, 03 Jun 2009)
Log Message: ----------- iTaSC: various improvements. Better cache handling: keep cache if new value identical to values in cache, only write cache on last reiteration on first timestep. Dynamic control of CopyPose gain. Modified Paths: -------------- branches/ge_dev/intern/itasc/Armature.cpp branches/ge_dev/intern/itasc/Armature.hpp branches/ge_dev/intern/itasc/Cache.cpp branches/ge_dev/intern/itasc/Cache.hpp branches/ge_dev/intern/itasc/CopyPose.cpp branches/ge_dev/intern/itasc/Distance.cpp branches/ge_dev/intern/itasc/MovingFrame.cpp branches/ge_dev/intern/itasc/Scene.cpp branches/ge_dev/intern/itasc/Scene.hpp branches/ge_dev/source/blender/ikplugin/intern/itasc_plugin.cpp Modified: branches/ge_dev/intern/itasc/Armature.cpp =================================================================== --- branches/ge_dev/intern/itasc/Armature.cpp 2009-06-03 15:14:09 UTC (rev 20602) +++ branches/ge_dev/intern/itasc/Armature.cpp 2009-06-03 15:17:52 UTC (rev 20603) @@ -13,7 +13,7 @@ namespace iTaSC { // a joint constraint is characterized by 5 values: tolerance, K, alpha, yd, yddot -static const unsigned int constraintCacheSize = sizeof(double)*5; +static const unsigned int constraintCacheSize = 5; std::string Armature::m_root = "root"; Armature::Armature(): @@ -24,6 +24,7 @@ m_neffector(0), m_finalized(false), m_cache(NULL), + m_buf(NULL), m_qCCh(-1), m_qCTs(0), m_yCCh(-1), @@ -48,6 +49,8 @@ if (*it != NULL) delete (*it); } + if (m_buf) + delete [] m_buf; m_constraints.clear(); } @@ -56,24 +59,27 @@ m_cache = _cache; m_qCCh = -1; m_yCCh = -1; + m_buf = NULL; if (m_cache) { // add a special channel for the joint m_qCCh = m_cache->addChannel(this, "q", m_qKdl.rows()*sizeof(double)); // for the constraints, instead of creating many different channels, we will // create a single channel for all the constraints if (m_nconstraint) { - m_yCCh = m_cache->addChannel(this, "y", m_nconstraint*constraintCacheSize); + m_yCCh = m_cache->addChannel(this, "y", m_nconstraint*constraintCacheSize*sizeof(double)); } + if (m_nconstraint) + m_buf = new double[m_nconstraint*constraintCacheSize]; // store the initial cache position at timestamp 0 pushQ(0); pushConstraints(0); } } - void Armature::pushQ(CacheTS timestamp) { if (m_qCCh >= 0) { - m_cache->addCacheItem(this, m_qCCh, timestamp, &m_qKdl(0), m_qKdl.rows()*sizeof(double)); + // try to keep the cache if the joints are the same + m_cache->addCacheVectorIfDifferent(this, m_qCCh, timestamp, &m_qKdl(0), m_qKdl.rows(), KDL::epsilon); m_qCTs = timestamp; } } @@ -99,8 +105,9 @@ void Armature::pushConstraints(CacheTS timestamp) { if (m_yCCh >= 0) { - double *item = (double*)m_cache->addCacheItem(this, m_yCCh, timestamp, NULL, m_nconstraint*constraintCacheSize); - if (item) { + double *buf = NULL; + if (m_nconstraint) { + double *item = m_buf; for (unsigned int i=0; i<m_nconstraint; i++) { JointConstraint_struct* pConstraint = m_constraints[i]; *item++ = pConstraint->values.feedback; @@ -110,6 +117,7 @@ *item++ = pConstraint->values.alpha; } } + m_cache->addCacheVectorIfDifferent(this, m_yCCh, timestamp, m_buf, m_nconstraint*constraintCacheSize, KDL::epsilon); m_yCTs = timestamp; } } @@ -324,7 +332,7 @@ m_qdotKdl(i)=m_qdot(i)*timestamp.realTimestep; Add(m_qKdl,m_qdotKdl,m_qKdl); - if (!timestamp.substep) { + if (!timestamp.substep && timestamp.cache) { pushQ(timestamp.cacheTimestamp); pushConstraints(timestamp.cacheTimestamp); } Modified: branches/ge_dev/intern/itasc/Armature.hpp =================================================================== --- branches/ge_dev/intern/itasc/Armature.hpp 2009-06-03 15:14:09 UTC (rev 20602) +++ branches/ge_dev/intern/itasc/Armature.hpp 2009-06-03 15:17:52 UTC (rev 20603) @@ -93,6 +93,7 @@ unsigned int m_neffector; bool m_finalized; Cache* m_cache; + double *m_buf; int m_qCCh; CacheTS m_qCTs; int m_yCCh; Modified: branches/ge_dev/intern/itasc/Cache.cpp =================================================================== --- branches/ge_dev/intern/itasc/Cache.cpp 2009-06-03 15:14:09 UTC (rev 20602) +++ branches/ge_dev/intern/itasc/Cache.cpp 2009-06-03 15:17:52 UTC (rev 20603) @@ -9,6 +9,8 @@ #include <malloc.h> #include "Cache.hpp" +#include <math.h> + namespace iTaSC { CacheEntry::~CacheEntry() @@ -457,7 +459,7 @@ return CACHE_ITEM_DATA_POINTER(item); } -const void *Cache::getCurrentCacheItem(const void *device, int id, unsigned int timestamp) +const CacheItem *Cache::getCurrentCacheItemInternal(const void *device, int id, CacheTS timestamp) { CacheMap::iterator it = m_cache.find(device); CacheEntry *entry; @@ -477,9 +479,35 @@ return NULL; if (buffer->m_firstTimestamp+item->m_timeOffset != timestamp) return NULL; - return CACHE_ITEM_DATA_POINTER(item); + return item; } +const void *Cache::getCurrentCacheItem(const void *device, int channel, unsigned int timestamp) +{ + const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp); + return (item) ? CACHE_ITEM_DATA_POINTER(item) : NULL; +} +double *Cache::addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *newdata, unsigned int length, double threshold) +{ + const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp); + unsigned int sizeW = CACHE_ITEM_SIZEW(item,length*sizeof(double)); + if (!item || item->m_sizeW != sizeW) + return (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double)); + double *olddata = (double*)CACHE_ITEM_DATA_POINTER(item); + if (!length) + return olddata; + double *ref = olddata; + double *v = newdata; + unsigned int i; + for (i=length; i>0; --i) { + if (fabs(*v-*ref) > threshold) + break; + *ref++ = *v++; + } + if (i) + olddata = (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double)); + return olddata; +} } Modified: branches/ge_dev/intern/itasc/Cache.hpp =================================================================== --- branches/ge_dev/intern/itasc/Cache.hpp 2009-06-03 15:14:09 UTC (rev 20602) +++ branches/ge_dev/intern/itasc/Cache.hpp 2009-06-03 15:17:52 UTC (rev 20603) @@ -22,7 +22,7 @@ /* macro to get item data position, item=CacheItem pointer */ #define CACHE_ITEM_DATA_POINTER(item) (void*)((unsigned char*)item+sizeof(CacheItem)+CACHE_ITEM_GAPB(item)) /* macro to get item size in 32bit words from item address and length, item=CacheItem pointer */ -#define CACHE_ITEM_SIZEW(item,length) (unsigned int)((sizeof(CacheItem)+CACHE_ITEM_GAPB(item)+((length+3)&~0x3))>>2) +#define CACHE_ITEM_SIZEW(item,length) (unsigned int)((sizeof(CacheItem)+CACHE_ITEM_GAPB(item)+(((length)+3)&~0x3))>>2) /* macto to move from one item to the next, item=CacheItem pointer, updated by the macro */ #define CACHE_NEXT_ITEM(item) ((item)+(item)->m_sizeW) #define CACHE_BLOCK_ITEM_ADDR(chan,buf,block) (&(buf)->m_firstItem+(((unsigned int)(block)<<chan->m_positionToBlockShiftW)+(buf)->lookup[block].m_offsetW)) @@ -38,7 +38,8 @@ CacheTS cacheTimestamp; unsigned int substep:1; unsigned int reiterate:1; - unsigned int dummy:30; + unsigned int cache:1; + unsigned int dummy:29; }; /* utility function to return second timestamp to millisecond */ @@ -74,6 +75,10 @@ */ struct CacheEntry; +struct CacheBuffer; +struct CacheItem; +struct CacheChannel; + class Cache { private: @@ -81,6 +86,7 @@ Dynamically updated when more devices create cache channels */ typedef std::map<const void *, struct CacheEntry*> CacheMap; CacheMap m_cache; + const CacheItem *getCurrentCacheItemInternal(const void *device, int channel, CacheTS timestamp); public: Cache(); @@ -103,6 +109,13 @@ return: error: NULL, success: pointer to item in cache */ void *addCacheItem(const void *device, int channel, CacheTS timestamp, void *data, unsigned int length); + /* specialized function to add a vector of double in the cache + It will first check if a vector exist already in the cache for the same timestamp + and compared the cached vector with the new values. + If all values are within threshold, the vector is updated but the cache is not deleted + for the future timestamps. */ + double *addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold); + /* returns the cache item with timestamp that is just before the given timestamp. returns the data pointer or NULL if there is no cache item before timestamp. On return, timestamp is updated with the actual timestamp of the item being returned. @@ -120,7 +133,6 @@ /* the following structures are not internal use only, they should not be used directly */ -struct CacheChannel; struct CacheEntry { CacheChannel *m_channelArray; // array of channels, automatically resized if more channels are created @@ -129,8 +141,6 @@ ~CacheEntry(); }; -struct CacheBuffer; -struct CacheItem; struct CacheChannel { struct CacheBuffer *m_firstBuffer; // first buffer of list Modified: branches/ge_dev/intern/itasc/CopyPose.cpp =================================================================== --- branches/ge_dev/intern/itasc/CopyPose.cpp 2009-06-03 15:14:09 UTC (rev 20602) +++ branches/ge_dev/intern/itasc/CopyPose.cpp 2009-06-03 15:17:52 UTC (rev 20603) @@ -14,6 +14,7 @@ namespace iTaSC { +const unsigned int maxPoseCacheSize = (2*(3+3*2)); CopyPose::CopyPose(unsigned int control_output, unsigned int dynamic_output, double accuracy, unsigned int maximum_iterations): ConstraintSet(), m_cache(NULL), @@ -105,7 +106,7 @@ } assert(_nc == m_nc); m_Jf=e_identity_matrix(6,6); - m_poseCacheSize = sizeof(double)*(((nrotCache)?(3+nrotCache*2):0)+((nposCache)?(3+nposCache*2):0)); + m_poseCacheSize = ((nrotCache)?(3+nrotCache*2):0)+((nposCache)?(3+nposCache*2):0); } CopyPose::~CopyPose() @@ -131,7 +132,7 @@ m_poseCCh = -1; if (m_cache) { // create one channel for the coordinates - m_poseCCh = m_cache->addChannel(this, "Xf", m_poseCacheSize); + m_poseCCh = m_cache->addChannel(this, "Xf", m_poseCacheSize*sizeof(double)); // don't save initial value, it will be recomputed from external pose //pushPose(0); } @@ -162,13 +163,16 @@ void CopyPose::pushPose(CacheTS timestamp) { if (m_poseCCh >= 0) { - double *item = (double*)m_cache->addCacheItem(this, m_poseCCh, timestamp, NULL, m_poseCacheSize); - if (item) { + if (m_poseCacheSize) { + double buf[maxPoseCacheSize]; + double *item = buf; if (m_outputDynamic & CTL_POSITION) item = pushValues(item, &m_pos, CTL_POSITIONX); if (m_outputDynamic & CTL_ROTATION) item = pushValues(item, &m_rot, CTL_ROTATIONX); - } + m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, m_poseCacheSize, KDL::epsilon); + } else + m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, NULL, 0, KDL::epsilon); m_poseCTs = timestamp; } } @@ -264,7 +268,7 @@ interpolateOutput(&m_pos, CTL_POSITIONX, timestamp); if (m_outputDynamic & CTL_ROTATION) @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs