iCub-main
Loading...
Searching...
No Matches
dynContact.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2011 RobotCub Consortium
3 * Author: Andrea Del Prete
4 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
5 *
6 */
7
8#include <iostream>
9#include <sstream>
10#include <iomanip>
11#include <string>
12#include "stdio.h"
13
14#include <yarp/os/ConnectionReader.h>
15#include <yarp/os/ConnectionWriter.h>
16#include <yarp/math/Math.h>
18#include <iCub/ctrl/math.h>
19
20using namespace std;
21using namespace yarp::os;
22using namespace yarp::sig;
23using namespace yarp::math;
24using namespace iCub::ctrl;
25using namespace iCub::skinDynLib;
26
27
28//~~~~~~~~~~~~~~~~~~~~~~
29// DYN CONTACT
30//~~~~~~~~~~~~~~~~~~~~~~
31unsigned long dynContact::ID = 1;
32//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37dynContact::dynContact(const BodyPart &_bodyPart, unsigned int _linkNumber, const Vector &_CoP){
38 init(_bodyPart, _linkNumber, _CoP);
39}
40//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41dynContact::dynContact(const BodyPart &_bodyPart, unsigned int _linkNumber, const Vector &_CoP, const Vector &_Mu){
42 init(_bodyPart, _linkNumber, _CoP, _Mu);
43}
44//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45dynContact::dynContact(const BodyPart &_bodyPart, unsigned int _linkNumber, const Vector &_CoP, const Vector &_Mu, const Vector &_Fdir){
46 init(_bodyPart, _linkNumber, _CoP, _Mu, _Fdir);
47}
48//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49void dynContact::init(const BodyPart &_bodyPart, unsigned int _linkNumber, const Vector &_CoP, const Vector &_Mu, const Vector &_Fdir){
50 contactId = ID++;
51 setBodyPart(_bodyPart);
52 setLinkNumber(_linkNumber);
53 setCoP(_CoP);
54 Mu.resize(3, 0.0);
55 Fdir.resize(3, 0.0);
56 F.resize(3, 0.0);
57 Fmodule = 0.0;
58
59 if(_Mu.size()==0)
60 muKnown = false;
61 else
62 fixMoment(_Mu);
63
64 if(_Fdir.size()==0)
65 fDirKnown = false;
66 else
67 fixForceDirection(_Fdir);
68}
69//~~~~~~~~~~~~~~~~~~~~~~
70// GET methods
71//~~~~~~~~~~~~~~~~~~~~~~
72Vector dynContact::getForceMoment() const{ return cat(F, Mu); }
73//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74const Vector& dynContact::getForce() const{ return F;}
75//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76const Vector& dynContact::getForceDirection() const{ return Fdir;}
77//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
78double dynContact::getForceModule() const{ return Fmodule;}
79//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80const Vector& dynContact::getMoment() const{ return Mu;}
81//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82const Vector& dynContact::getCoP() const{ return CoP;}
83//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84unsigned int dynContact::getLinkNumber() const{ return linkNumber;}
85//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90unsigned long dynContact::getId() const{ return contactId;}
91
92//~~~~~~~~~~~~~~~~~~~~~~
93// IS methods
94//~~~~~~~~~~~~~~~~~~~~~~
95bool dynContact::isMomentKnown() const{ return muKnown;}
96//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98//~~~~~~~~~~~~~~~~~~~~~~
99// SET methods
100//~~~~~~~~~~~~~~~~~~~~~~
101bool dynContact::setForce(const Vector &_F){
102 if(!checkVectorDim(_F, 3, "force"))
103 return false;
104 F = _F;
105 Fmodule = norm(_F);
106 if(Fmodule!=0.0)
107 Fdir = _F / Fmodule;
108 return true;
109}
110//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111bool dynContact::setForceModule(double _Fmodule){
112 if(_Fmodule<0){
113 if(verbose)
114 fprintf(stderr, "Error in dynContact: negative force module, %f\n", _Fmodule);
115 return false;
116 }
117 Fmodule = _Fmodule;
118 F=Fmodule*Fdir;
119 return true;
120}
121//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122bool dynContact::setForceDirection(const Vector &_Fdir){
123 if(!checkVectorDim(_Fdir, 3, "force direction"))
124 return false;
125 double FdirNorm = norm(_Fdir);
126 if(FdirNorm != 0.0)
127 Fdir = _Fdir / FdirNorm;
128 F=Fmodule*Fdir;
129 return true;
130}
131//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132bool dynContact::setMoment(const Vector &_Mu){
133 if(!checkVectorDim(_Mu, 3, "moment"))
134 return false;
135 Mu = _Mu;
136 return true;
137}
138//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139bool dynContact::setForceMoment(const yarp::sig::Vector &_F, const yarp::sig::Vector &_Mu){
140 return setForce(_F) && setMoment(_Mu);
141}
142//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
143bool dynContact::setForceMoment(const yarp::sig::Vector &_FMu){
144 if(!checkVectorDim(_FMu, 6, "force moment"))
145 return false;
146 bool res = setForce(_FMu.subVector(0,2));
147 return res && setMoment(_FMu.subVector(3,5));
148}
149//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150bool dynContact::setCoP(const Vector &_CoP){
151 if(!checkVectorDim(_CoP, 3, "Center of pressure"))
152 return false;
153 CoP = _CoP;
154 return true;
155}
156//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157void dynContact::setLinkNumber(unsigned int _linkNum){
158 linkNumber = _linkNum;
159}
160//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
162 bodyPart = _bodyPart;
163}
164//~~~~~~~~~~~~~~~~~~~~~~
165// FIX/UNFIX methods
166//~~~~~~~~~~~~~~~~~~~~~~
167bool dynContact::fixForceDirection(const Vector &_Fdir){
168 if(setForceDirection(_Fdir)){
169 fDirKnown = true;
170 return true;
171 }
172 return false;
173}
174//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176 return fixMoment(zeros(3));
177}
178//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179bool dynContact::fixMoment(const Vector &_Mu){
180 if(setMoment(_Mu)){
181 muKnown = true;
182 return true;
183 }
184 return false;
185}
186//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191//~~~~~~~~~~~~~~~~~~~~~~
192// SERIALIZATION methods
193//~~~~~~~~~~~~~~~~~~~~~~
194bool dynContact::write(ConnectionWriter& connection) const{
195 // represent a dynContact as a list of 4 elements that are:
196 // - a list of 3 int, i.e. contactId, bodyPart, linkNumber
197 // - a list of 3 double, i.e. the CoP
198 // - a list of 3 double, i.e. the force
199 // - a list of 3 double, i.e. the moment
200
201 connection.appendInt32(BOTTLE_TAG_LIST);
202 connection.appendInt32(4);
203 // list of 3 int, i.e. contactId, bodyPart, linkNumber
204 connection.appendInt32(BOTTLE_TAG_LIST + BOTTLE_TAG_INT32);
205 connection.appendInt32(3);
206 connection.appendInt32(contactId);
207 connection.appendInt32(bodyPart); // left_arm, right_arm, ...
208 connection.appendInt32(linkNumber);
209 // list of 3 double, i.e. the CoP
210 connection.appendInt32(BOTTLE_TAG_LIST + BOTTLE_TAG_FLOAT64);
211 connection.appendInt32(3);
212 for(int i=0;i<3;i++) connection.appendFloat64(CoP[i]);
213 // list of 3 double, i.e. the force
214 connection.appendInt32(BOTTLE_TAG_LIST + BOTTLE_TAG_FLOAT64);
215 connection.appendInt32(3);
216 for(int i=0;i<3;i++) connection.appendFloat64(F[i]);
217 // list of 3 double, i.e. the moment
218 connection.appendInt32(BOTTLE_TAG_LIST + BOTTLE_TAG_FLOAT64);
219 connection.appendInt32(3);
220 for(int i=0;i<3;i++) connection.appendFloat64(Mu[i]);
221
222 // if someone is foolish enough to connect in text mode,
223 // let them see something readable.
224 connection.convertTextMode();
225
226 return !connection.isError();
227}
228//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229bool dynContact::read(ConnectionReader& connection){
230 // auto-convert text mode interaction
231 connection.convertTextMode();
232
233 // represent a dynContact as a list of 4 elements that are:
234 // - a list of 3 int, i.e. contactId, bodyPart, linkNumber
235 // - a list of 3 double, i.e. the CoP
236 // - a list of 3 double, i.e. the force
237 // - a list of 3 double, i.e. the moment
238 if(connection.expectInt32()!= BOTTLE_TAG_LIST || connection.expectInt32()!=4)
239 return false;
240 // - a list of 3 int, i.e. contactId, bodyPart, linkNumber
241 if(connection.expectInt32()!=BOTTLE_TAG_LIST+BOTTLE_TAG_INT32 || connection.expectInt32()!=3)
242 return false;
243 contactId = connection.expectInt32();
244 bodyPart = (BodyPart)connection.expectInt32();
245 linkNumber = connection.expectInt32();
246 // - a list of 3 double, i.e. the CoP
247 if(connection.expectInt32()!=BOTTLE_TAG_LIST+BOTTLE_TAG_FLOAT64 || connection.expectInt32()!=3)
248 return false;
249 for(int i=0;i<3;i++) CoP[i] = connection.expectFloat64();
250 // - a list of 3 double, i.e. the force
251 if(connection.expectInt32()!=BOTTLE_TAG_LIST+BOTTLE_TAG_FLOAT64 || connection.expectInt32()!=3)
252 return false;
253 for(int i=0;i<3;i++) F[i] = connection.expectFloat64();
254 setForce(F);
255 // - a list of 3 double, i.e. the moment
256 if(connection.expectInt32()!=BOTTLE_TAG_LIST+BOTTLE_TAG_FLOAT64 || connection.expectInt32()!=3)
257 return false;
258 for(int i=0;i<3;i++) Mu[i] = connection.expectFloat64();
259
260 return !connection.isError();
261}
262//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
263string dynContact::toString(int precision) const{
264 stringstream res;
265 res<< "Contact id: "<< contactId<< ", Body part: "<< BodyPart_s[bodyPart]<< ", link: "<< linkNumber<< ", CoP: "<<
266 CoP.toString(precision)<< ", F: "<< F.toString(precision)<< ", M: "<< Mu.toString(precision);
267 return res.str();
268}
269//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
270void dynContact::setVerbose(unsigned int verb){
271 verbose = verb;
272}
273//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
274bool dynContact::checkVectorDim(const Vector &v, unsigned int dim, const string &descr){
275 if(v.length() != dim){
276 if(verbose)
277 fprintf(stderr, "Error in dynContact: unexpected dimension of vector %s, %d\n", descr.c_str(), (int)v.length());
278 return false;
279 }
280 return true;
281}
282//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283
284
virtual unsigned int getLinkNumber() const
Get the link number (where 0 is the first link of the chain).
bool checkVectorDim(const yarp::sig::Vector &v, unsigned int dim, const std::string &descr="")
unsigned int verbose
verbosity flag
Definition dynContact.h:80
yarp::sig::Vector F
contact force
Definition dynContact.h:68
virtual const yarp::sig::Vector & getForce() const
Get the contact force.
virtual bool write(yarp::os::ConnectionWriter &connection) const override
Write dynContact to a connection as a list of 4 elements, that are:
virtual bool setForce(const yarp::sig::Vector &_F)
Set the contact force.
virtual bool setForceDirection(const yarp::sig::Vector &_Fdir)
Set the direction of the contact force.
yarp::sig::Vector Mu
contact moment
Definition dynContact.h:72
bool muKnown
True if the moment applied at the contact point is known.
Definition dynContact.h:75
virtual void unfixMoment()
Set the flag muKnown to false so that when estimating the contact wrenches the solver estimates also ...
unsigned int linkNumber
number of the link where the contact is applied
Definition dynContact.h:62
yarp::sig::Vector Fdir
contact force direction (unit vector)
Definition dynContact.h:66
virtual void setBodyPart(BodyPart _bodyPart)
Set the body part of this contact.
virtual bool setCoP(const yarp::sig::Vector &_CoP)
Set the contact center of pressure in link reference frame.
virtual const yarp::sig::Vector & getMoment() const
Get the contact moment.
virtual bool setForceModule(double _Fmodule)
Set the contact force module.
void init(const BodyPart &_bodyPart, unsigned int _linkNumber, const yarp::sig::Vector &_CoP, const yarp::sig::Vector &_Mu=yarp::sig::Vector(0), const yarp::sig::Vector &_Fdir=yarp::sig::Vector(0))
virtual BodyPart getBodyPart() const
Get the body part of the contact.
virtual unsigned long getId() const
Get the id of this contact.
virtual void unfixForceDirection()
Set the flag fDirKnown to false so that when estimating the contact wrenches the solver estimates als...
virtual std::string getBodyPartName() const
Get the name of the contact body part.
virtual const yarp::sig::Vector & getCoP() const
Get the contact center of pressure expressed in the link reference frame.
static unsigned long ID
Definition dynContact.h:55
virtual std::string toString(int precision=-1) const
Convert this contact into a string.
virtual void setVerbose(unsigned int verb=VERBOSE)
Set the verbosity level of comments during operations.
virtual void setLinkNumber(unsigned int _linkNum)
Set the contact link number (0 is the first link)
virtual bool fixForceDirection(const yarp::sig::Vector &_Fdir)
Fix the direction of the contact force.
virtual bool fixMoment()
Equivalent to calling fixMoment(zeros(3)).
yarp::sig::Vector CoP
center of pressure of the contact expressed w.r.t. the reference frame of the link
Definition dynContact.h:64
virtual const yarp::sig::Vector & getForceDirection() const
Get the contact force direction.
virtual yarp::sig::Vector getForceMoment() const
Get the contact force and moment in a single (6x1) vector.
BodyPart bodyPart
part of the body of the robot where the contact is applied
Definition dynContact.h:60
virtual bool isForceDirectionKnown() const
Get true if the direction of the force applied at this contact is known a-priori.
dynContact()
Default constructor.
virtual bool isMomentKnown() const
Get true if the moment applied at this contact is known a-priori.
virtual bool read(yarp::os::ConnectionReader &connection) override
virtual double getForceModule() const
Get the contact force module.
bool fDirKnown
True if the direction of the force applied at the contact point is known.
Definition dynContact.h:77
double Fmodule
contact force module
Definition dynContact.h:70
virtual bool setForceMoment(const yarp::sig::Vector &_F, const yarp::sig::Vector &_Mu)
Set the contact force and moment.
virtual bool setMoment(const yarp::sig::Vector &_Mu)
Set the contact moment.
zeros(2, 2) eye(2
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
const std::string BodyPart_s[]
Definition common.h:49
fprintf(fid,'\n')