15 const double* operator()(
const double& element)
const {
return &element; }
20 double operator()(
const double* element)
const {
return *element; }
26 VariableParenthood::VariableParenthood() throw()
27 : startIndexInParentMap(0)
36 Variable::Variable(
const std::string& name)
39 , timeDerivative_(0x0, false)
40 , timePrimitive_(0x0, false)
48 if(timePrimitive_.var_ && timePrimitive_.owns_)
50 delete timePrimitive_.var_;
51 timePrimitive_ = VariablePtr(0x0,
false);
53 else if(timePrimitive_.var_)
54 timePrimitive_.var_->timeDerivative_ = VariablePtr(0x0,
false);
56 if(timeDerivative_.var_ && timeDerivative_.owns_)
58 delete timeDerivative_.var_;
59 timeDerivative_ = VariablePtr(0x0,
false);
61 else if(timeDerivative_.var_)
62 timeDerivative_.var_->timePrimitive_ = VariablePtr(0x0,
false);
67 return *memoryMap_[i];
72 if (i >= memoryMap_.size())
74 std::stringstream err;
75 err <<
"[ocra::Variable::at] index " << i <<
" out of bound in variable " << name_ <<
"; size is " << memoryMap_.size();
76 throw std::runtime_error(err.str());
78 return *memoryMap_[i];
83 ocra_assert(static_cast<int>(memoryMap_.size()) >= 0 &&
"This is really bad, we have such a huge memory block that an int can't hold its size");
84 return static_cast<int>(memoryMap_.size());
87 Variable::operator
const VectorXd& ()
const 103 propagate<EVT_CHANGE_VALUE>();
110 return *timeDerivative_.var_;
117 return *timePrimitive_.var_;
122 return timeDerivative_;
127 return timePrimitive_;
134 std::stringstream err;
135 err <<
"[ocra::Variable::createTimeDerivative] This variable already has a derivative, named " << timeDerivative_.var_->name_;
136 throw std::runtime_error(err.str());
140 timeDerivative_.owns_ =
true;
141 ocra_assert(timeDerivative_ &&
"The derived class violated its contract: do_createTimeDerivative must return non null pointer!");
143 timeDerivative_.var_->timePrimitive_.var_ =
this;
144 timeDerivative_.var_->timePrimitive_.owns_ =
false;
151 std::stringstream err;
152 err <<
"[ocra::Variable::createTimePrimitive] This variable already has a primitive, named " << timePrimitive_.var_->name_;
153 throw std::runtime_error(err.str());
157 timePrimitive_.owns_ =
true;
158 ocra_assert(timePrimitive_ &&
"The derived class violated its contract: do_createTimePrimitive must return non null pointer!");
160 timePrimitive_.var_->timeDerivative_.var_ =
this;
161 timePrimitive_.var_->timeDerivative_.owns_ =
false;
184 std::vector<double> subVar_backup, thisVar_backup;
185 std::transform(subVar.memoryMap_.begin(), subVar.memoryMap_.end(), std::back_inserter(subVar_backup), get_value());
186 std::transform(thisVar.memoryMap_.begin(), thisVar.memoryMap_.end(), std::back_inserter(thisVar_backup), get_value());
189 double** subVarMemoryMap =
const_cast<double**
>(&subVar.memoryMap_[0]);
190 double** thisVarMemoryMap =
const_cast<double**
>(&thisVar.memoryMap_[0]);
192 for(
int i = 0; i < subVar.
getSize(); ++i)
193 *subVarMemoryMap[i] = -1;
195 for(
int i = 0; i < thisVar.
getSize(); ++i)
196 *thisVarMemoryMap[i] = static_cast<double>(i);
199 mapping.reserve(subVar.
getSize());
200 for(
int i = 0; i < subVar.
getSize(); ++i)
202 int d =
static_cast<int>(subVar[i]);
208 mapping.push_back(d);
213 double** subVarMemoryMap =
const_cast<double**
>(&subVar.memoryMap_[0]);
214 double** thisVarMemoryMap =
const_cast<double**
>(&thisVar.memoryMap_[0]);
216 for(
int i = 0; i < subVar.
getSize(); ++i)
217 *subVarMemoryMap[i] = subVar_backup[i];
219 for(
int i = 0; i < thisVar.
getSize(); ++i)
220 *thisVarMemoryMap[i] = thisVar_backup[i];
230 connect<EVT_CHANGE_VALUE>(parent.getParent(), &CompositeVariable::onChildValueChanged);
231 connect<EVT_RESIZE>(parent.getParent(), &CompositeVariable::onChildValueChanged);
232 connect<EVT_CHANGE_DEPENDENCIES>(parent.getParent(), &CompositeVariable::onChildValueChanged);
234 const parenthood_t* prevChild = parent.getPreviousChild();
238 parent.getInfo().startIndexInParentMap =
239 prevChild->getInfo().startIndexInParentMap + prevChild->getChild().memoryMap_.size();
244 disconnect<EVT_CHANGE_VALUE>(parent.getParent(), &CompositeVariable::onChildValueChanged);
245 disconnect<EVT_RESIZE>(parent.getParent(), &CompositeVariable::onChildValueChanged);
246 disconnect<EVT_CHANGE_DEPENDENCIES>(parent.getParent(), &CompositeVariable::onChildValueChanged);
248 parent.getInfo().startIndexInParentMap = 0;
253 static const int shiftPerDepthLevel = 3;
254 const int numSpaces = depth * shiftPerDepthLevel;
256 for(
int i = 0; i < numSpaces; ++i)
259 os << name_ <<
"(" << memoryMap_.size() <<
")" << std::endl;
262 void Variable::insertInMemoryMap(
const parenthood_t& child,
size_t whereInChild, std::vector<const double*>::const_iterator start, std::vector<const double*>::const_iterator end)
264 size_t indexInMap = child.getInfo().startIndexInParentMap + whereInChild;
265 memoryMap_.insert(memoryMap_.begin() + indexInMap, start, end);
270 nextChild->getInfo().startIndexInParentMap +=
std::distance(start, end);
271 nextChild = nextChild->getNextChild();
279 const parenthood_t& child,
size_t whereInChild, std::vector<const double*>::const_iterator start, std::vector<const double*>::const_iterator end)
281 obj.insertInMemoryMap(child, whereInChild, start, end);
284 void Variable::removeFromMemoryMap(
const parenthood_t& child,
size_t whereInChild,
size_t numElements)
286 size_t indexInMap = child.getInfo().startIndexInParentMap + whereInChild;
287 memoryMap_.erase(memoryMap_.begin() + indexInMap, memoryMap_.begin() + indexInMap + numElements);
292 nextChild->getInfo().startIndexInParentMap -= numElements;
293 nextChild = nextChild->getNextChild();
302 obj.removeFromMemoryMap(child, whereInChild, numElements);
307 return obj.memoryMap_;
310 void Variable::updateValue()
const 312 if(!memoryMap_.size())
313 throw std::runtime_error(
"[ocra::Variable::updateValue] cannot update value when the size of the variable is 0.");
315 value_.resize( static_cast<int>(memoryMap_.size()) );
316 for (
int i = 0; i < static_cast<int>(memoryMap_.size()); ++i)
317 value_[i] = *memoryMap_[i];
318 updateValue_ =
false;
321 void Variable::onChildValueChanged(
int timestamp)
335 std::vector<const double*>& memoryMap =
getMemoryMap(*
this);
336 std::transform(memory_.begin(), memory_.end(), std::back_inserter(memoryMap), get_address());
346 std::vector<const double*>& memoryMap =
getMemoryMap(*
this);
351 memory_.resize(newSize);
353 std::transform(memory_.begin(), memory_.end(), std::back_inserter(memoryMap), get_address());
358 propagate<EVT_RESIZE>();
363 if (value.size() != memory_.size())
364 throw std::runtime_error(
"[ocra::BaseVariable::setValue] Sizes don't match");
366 for(
int i = 0; i < value.size(); ++i)
367 memory_[i] = value[i];
431 for(
size_t i = 0; i < vars.size(); ++i)
444 throw std::runtime_error(
"[ocra::BaseVariable::setValue] Sizes don't match");
449 const int size = (*it)->getChild().getSize();
450 (*it)->getChild().setValue(value.segment(start, size));
494 const std::vector<const double*>& childMemoryMap =
getMemoryMap(child.getChild());
496 propagate<EVT_CHANGE_DEPENDENCIES>();
497 if (child.getChild().getSize()>0)
498 propagate<EVT_RESIZE>();
504 propagate<EVT_CHANGE_DEPENDENCIES>();
505 if (child.getChild().getSize()>0)
506 propagate<EVT_RESIZE>();
522 bool exceptionCaught =
false;
523 std::runtime_error toRethrow(
"");
531 catch(std::runtime_error& e) {
534 exceptionCaught =
true;
554 bool exceptionCaught =
false;
555 std::runtime_error toRethrow(
"");
563 catch(std::runtime_error& e) {
566 exceptionCaught =
true;
591 throw std::runtime_error(
"[ocra::CompositeVariable::do_add] The child variable must have at least the same max order of integration as the parent");
593 while(ptr && childPtr)
599 throw std::runtime_error(
"[ocra::CompositeVariable::do_add] The child variable must have at least the same max order of differentiation as the parent");
610 while(ptr && childPtr)
631 while(ptr && childPtr)
Variable * do_createTimePrimitive(const std::string &name)
size_t do_getNumberOfChildren() const
Always return 0.
int isDescendantOf(const CompositeDerived &node) const
Returns the number of levels that separates the component from a potential parent.
virtual Variable & getTimeDerivative()
Get the time derivative/primitive of the variable.
void detach(ComponentDerived &child)
Erases a Parenthood bond between a Composite and a Component.
virtual const std::string & getName() const
CompositeVariable(const std::string &name)
void do_setValue(const VectorXd &value)
This method will attempt to assign a given value to the memory map.
const VectorXd & getValue() const
int isAncestorOf_impl(const Variable &node) const
void onAttachedChild(const parenthood_t &child)
static std::vector< const double * > & getMemoryMap(Variable &obj)
void setValue(const VectorXd &value)
void onDetachedParent(const parenthood_t &parent)
const_iterator parents_begin() const
Iterator range on the set of parents.
CompositeVariable & getTimePrimitive()
const_iterator parents_end() const
void printTree_impl(int depth, std::ostream &os) const
CompositeDerived & getParent() const
Access to parenthood info, parent, child and their ranks, see constructor postconditions and class de...
size_t getNumberOfChildren() const
Returns 0 in BaseVariable and the number of childhoods otherwise.
Component< Variable, CompositeVariable, VariableParenthood >::parenthood_t parenthood_t
void do_setValue(const VectorXd &value)
This method will attempt to assign a given value to the memory map.
void getRelativeMappingOf(const Variable &subVariable, std::vector< int > &mapping) const
Returns the indexes of a subvariable in the variable.
Variable & operator()(size_t i)
void onAttachedParent(const parenthood_t &parent)
const parenthood_t_ & getChildhood(size_t i) const
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
size_t getNumParenthoods() const
Basic access to the parents.
static void callRemoveFromMemoryMap(Variable &obj, const parenthood_t &child, size_t whereInChild, size_t numElements)
CompositeVariable & getTimeDerivative()
Get the time derivative/primitive of the variable.
void attach(ComponentDerived &child)
Attaches a Component to a Composite by simply creating a Parenthood bond between them.
bool hasTimeDerivative() const
void createTimeDerivative(const std::string &name)
Creates a time derivative/primitive with a given name.
double at(size_t i) const
void printSubTree(int depth, std::ostream &os) const
Overload in ComponentDerived and CompositeDerived to simply call printTree_impl().
virtual ~Variable()=0
The variable is automatically detached from parents and children at destruction.
double operator[](size_t i) const
Variable * do_createTimePrimitive(const std::string &name)
virtual void do_setValue(const VectorXd &value)=0
This method will attempt to assign a given value to the memory map.
static void callInsertInMemoryMap(Variable &obj, const parenthood_t &child, size_t whereInChild, std::vector< const double * >::const_iterator start, std::vector< const double * >::const_iterator end)
Proxy to the implementation of memory maps update.
const parenthood_t & getParenthood(size_t i) const
virtual Variable * do_createTimeDerivative(const std::string &name)=0
These methods must be overloaded in children classes to perform instantiation and return pointers to ...
This class represents a variable in a mathematical sense.
BaseVariable(const std::string &name, size_t size)
Builds a leaf variable, i.e. a variable that is not composed of other variables.
void printNode(int depth, std::ostream &os) const
Prints the name of the variables; preprends 3*depth blank spaces.
void printSubTree(int depth, std::ostream &os) const
Overload in ComponentDerived and CompositeDerived to simply call printTree_impl().
int isAncestorOf(const Variable &var) const
Returns the number of levels that separate the component from a potential child.
void createTimePrimitive(const std::string &name)
size_t getNumChildhoods() const
Basic access to the children.
void resize(size_t newSize)
std::vector< parenthood_t * >::iterator iterator
virtual Variable & getTimePrimitive()
bool isBaseVariable() const
virtual Variable * do_createTimePrimitive(const std::string &name)=0
CompositeVariable & addByMerge(Variable &v)
BaseVariable & getTimePrimitive()
CompositeVariable & add(Variable &child)
Attach/detach the child to/from this node.
BaseVariable & getTimeDerivative()
Get the time derivative/primitive of the variable.
A concatenation of base variables and other composite variables.
void clear()
Detaches all children.
ComponentDerived & getChild() const
Variable * do_createTimeDerivative(const std::string &name)
void onDetachedChild(const parenthood_t &child)
#define ocra_assert(ocra_expression)
const_iterator_ children_end() const
Declaration file of the Variable class.
virtual bool isBaseVariable() const
double distance(double a, double b)
Variable * do_createTimeDerivative(const std::string &name)
CompositeVariable & remove(Variable &child)
void printTree_impl(int depth, std::ostream &os) const
virtual size_t do_getNumberOfChildren() const =0
Returns 0 in {Wrap|Base}Variable and the number of childhoods otherwise.
Implements a basic variable.
bool hasTimePrimitive() const
const_iterator_ children_begin() const
Iterator range on the children.
size_t do_getNumberOfChildren() const
Always return getNumChildhoods.
int isAncestorOf(const Variable &var) const
Returns the number of levels that separate the component from a potential child.