Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * Extrapolation.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _EXTRAPOLATION_HPP_ 00033 #define _EXTRAPOLATION_HPP_ 00034 00035 #include "TemporalValue.hpp" 00036 00037 namespace Sirikata { 00038 00039 template<typename Value, typename TimeType> 00040 class ExtrapolatorBase { 00041 public: 00042 virtual ~ExtrapolatorBase(){} 00043 virtual bool needsUpdate(const TimeType&now, const Value&actualValue)const=0; 00044 virtual Value extrapolate(const TimeType&now)const=0; 00045 virtual TimeType lastUpdateTime()const=0; 00046 virtual const Value& lastValue()const=0; 00047 virtual ExtrapolatorBase<Value, TimeType>& resetValue(const TimeType&now, const Value&actualValue)=0; 00048 virtual ExtrapolatorBase<Value, TimeType>& updateValue(const TimeType&now, const Value&actualValue)=0; 00049 virtual bool propertyHolds(const TimeType&time, const std::tr1::function<bool(const Value&)>&)const=0; 00050 }; 00051 00052 template<typename Value> 00053 class Extrapolator : public virtual ExtrapolatorBase<Value, Time> { 00054 }; 00055 00056 00057 template <typename Value, typename UpdatePredicate, typename TimeType, typename DurationType> 00058 class TimedWeightedExtrapolatorBase : public virtual ExtrapolatorBase<Value, TimeType>, protected UpdatePredicate { // Use protected inheritence for low cost inclusing, zero cost 00059 // if the class is empty 00060 protected: 00061 enum ValueTimes{PAST=0,PRESENT=1, MAXSAMPLES}; 00062 typedef TemporalValueBase<Value, TimeType> TemporalValueType; 00063 TemporalValueType mValuePast; 00064 TemporalValueType mValuePresent; 00065 DurationType mFadeTime; 00066 public: 00067 TimedWeightedExtrapolatorBase(const DurationType&fadeTime, const TimeType&t, const Value&actualValue, const UpdatePredicate&needsUpdate) 00068 : ExtrapolatorBase<Value, TimeType>(), 00069 UpdatePredicate(needsUpdate), 00070 mValuePast(t,actualValue), 00071 mValuePresent(t,actualValue), 00072 mFadeTime(fadeTime) 00073 {} 00074 virtual ~TimedWeightedExtrapolatorBase(){} 00075 virtual bool needsUpdate(const TimeType&now,const Value&actualValue) const{ 00076 const UpdatePredicate* mNeedsUpdate=this; 00077 return (*mNeedsUpdate)(actualValue, extrapolate(now)); 00078 } 00079 Value extrapolate(const TimeType&t) const 00080 { 00081 DurationType timeSinceUpdate = std::max(DurationType::zero(),t-lastUpdateTime()); 00082 if (mFadeTime<=timeSinceUpdate) { 00083 return mValuePresent.extrapolate(t); 00084 }else{ 00085 return mValuePast.extrapolate(t) 00086 .blend(mValuePresent.extrapolate(t), 00087 (float32)(timeSinceUpdate/mFadeTime)); 00088 } 00089 } 00090 const Value& lastValue() const { 00091 return mValuePresent.value(); 00092 } 00093 TimeType lastUpdateTime()const{ 00094 return mValuePresent.time(); 00095 } 00096 ExtrapolatorBase<Value, TimeType>& updateValue(const TimeType&t, const Value&l) { 00097 mValuePast=TemporalValueType(t,extrapolate(t)); 00098 mValuePresent.updateValue(t,l); 00099 return *this; 00100 } 00101 ExtrapolatorBase<Value, TimeType>& resetValue(const TimeType&t, const Value&l) { 00102 mValuePresent.updateValue(t,l); 00103 mValuePast = mValuePresent; 00104 return *this; 00105 } 00106 template <class Functor> bool templatedPropertyHolds(const TimeType&t, const Functor &f)const{ 00107 DurationType timeSinceUpdate=t-lastUpdateTime(); 00108 if (timeSinceUpdate<mFadeTime) { 00109 return f(mValuePast.value())&&f(mValuePresent.value()); 00110 }else { 00111 return f(mValuePresent.value()); 00112 } 00113 } 00114 virtual bool propertyHolds(const TimeType&time, const std::tr1::function<bool(const Value&)>&f)const{ 00115 return templatedPropertyHolds(time,f); 00116 } 00117 }; 00118 00119 template <typename Value, typename UpdatePredicate> 00120 class TimedWeightedExtrapolator : public TimedWeightedExtrapolatorBase<Value, UpdatePredicate, Time, Duration>, public Extrapolator<Value> { 00121 public: 00122 TimedWeightedExtrapolator(const Duration&fadeTime, const Time&t, const Value&actualValue, const UpdatePredicate&needsUpdate) 00123 : TimedWeightedExtrapolatorBase<Value, UpdatePredicate, Time, Duration>(fadeTime, t, actualValue, needsUpdate) 00124 {} 00125 virtual bool needsUpdate(const Time&now, const Value&actualValue) const { 00126 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::needsUpdate(now,actualValue); 00127 } 00128 virtual ExtrapolatorBase<Value, Time>& updateValue(const Time&t, const Value&l) { 00129 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::updateValue(t,l); 00130 } 00131 virtual ExtrapolatorBase<Value, Time>& resetValue(const Time&t, const Value&l) { 00132 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::resetValue(t,l); 00133 } 00134 const Value& lastValue() const { 00135 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::lastValue(); 00136 } 00137 virtual bool propertyHolds(const Time&time, const std::tr1::function<bool(const Value&)>&f)const{ 00138 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::propertyHolds(time,f); 00139 } 00140 virtual Value extrapolate(const Time&t) const { 00141 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::extrapolate(t); 00142 } 00143 virtual Time lastUpdateTime()const{ 00144 return this->Sirikata::TimedWeightedExtrapolatorBase<Value,UpdatePredicate,Time,Duration>::lastUpdateTime(); 00145 } 00146 00147 }; 00148 00149 } 00150 #endif