iCub-main
ImuFilter.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 iCub Facility - Istituto Italiano di Tecnologia
3  * Author: Ugo Pattacini, Nicolo' Genesio
4  * email: ugo.pattacini@iit.it, nicolo.genesio@iit.it
5  * Permission is granted to copy, distribute, and/or modify this program
6  * under the terms of the GNU General Public License, version 2 or any
7  * later version published by the Free Software Foundation.
8  *
9  * A copy of the license can be found at
10  * http://www.robotcub.org/icub/license/gpl.txt
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details
16 */
17 
18 #include "ImuFilter.h"
19 #include <yarp/os/LogStream.h>
20 #include <cstring>
21 #include <cmath>
22 
23 #include <yarp/os/Time.h>
24 
25 
26 using namespace std;
27 using namespace yarp::os;
28 using namespace yarp::sig;
29 
30 namespace yarp {
31 namespace dev {
32 
33 ImuFilter::ImuFilter(): gyroFilt(1,Vector(3,0.0)), magFilt(1,Vector(3,0.0)),
34  velEst(40,0.05), biasInt(0.0,Vector(3,0.0)),
35  PassThroughInertial(), PeriodicThread(0.0)
36 {
37 }
38 
40  return true;
41 }
43 
44  bool ok{true};
45  double ts{0.0};
46  Vector gyroFiltered, magn;
47 
50  yError()<<"imuFilter: the imu is not attached";
51  this->askToStop();
52  return;
53  }
54  ok &= PassThroughInertial::proxyIGyro->getThreeAxisGyroscopeStatus(0) == MAS_OK;
55  ok &= PassThroughInertial::proxyIGyro->getThreeAxisGyroscopeMeasure(0, gyro, gyroTs);
56 
57  if (!ok){
58  yError()<<"imuFilter: unable to get gyro";
59  return;
60  }
61 
62  if (std::fabs(gyroTs - prevTs) < 1e-6 ){
63  return;
64  }
65 
66  ok &= PassThroughInertial::proxyIMagn->getThreeAxisMagnetometerStatus(0) == MAS_OK;
67  ok &= PassThroughInertial::proxyIMagn->getThreeAxisMagnetometerMeasure(0, magn, ts);
68 
69  if (!ok){
70  yError()<<"imuFilter: unable to get magnetometer measures";
71  return;
72  }
73 
74  stampBias.update(ts);
75  double t0=Time::now();
76 
77  m_mutex.lock();
78  gyroFiltered = gyroFilt.filt(gyro);
79 
80  gyro -= gyroBias;
81  gyroFiltered -= gyroBias;
82  m_mutex.unlock();
83 
84  Vector mag_filt=magFilt.filt(magn);
85  double magVel=yarp::math::norm(velEst.estimate(iCub::ctrl::AWPolyElement(mag_filt,stampBias.getTime())));
86 
87  adaptGyroBias=adaptGyroBias?(magVel<mag_vel_thres_up):(magVel<mag_vel_thres_down);
88  gyroBias=biasInt.integrate(adaptGyroBias?gyroFiltered:Vector(3,0.0));
89  double dt=Time::now()-t0;
90 
91  if (bPort.getOutputCount()>0)
92  {
93  bPort.prepare()=gyroBias;
94  bPort.setEnvelope(stampBias);
95  bPort.write();
96  }
97 
98  if (verbose)
99  {
100  yInfo("imuFilter: magVel = %g => [%s]",magVel,adaptGyroBias?"adapt-gyroBias":"no-adaption");
101  yInfo("imuFilter: gyro = %s",gyro.toString(3,3).c_str());
102  yInfo("imuFilter: gyroBias = %s",gyroBias.toString(3,3).c_str());
103  yInfo("imuFilter: dt = %.0f [us]",dt*1e6);
104  yInfo("\n");
105  }
106  prevTs = gyroTs;
107 }
109 
110 //DEVICE DRIVER
111 bool ImuFilter::open(yarp::os::Searchable& config)
112 {
113  bool ok = true;
114 
115  // opening comunication ports
116  ok &= PassThroughInertial::open(config);
117 
118  if (!ok) {
119  yError()<<"ImuFilter: failed to open proxy device";
120  return false;
121  }
122 
123  string name=config.check("name",Value("imuFilter")).asString();
124  string robot=config.check("robot",Value("icub")).asString();
125  size_t gyro_order=(size_t)config.check("gyro-order",Value(5)).asInt32();
126  size_t mag_order=(size_t)config.check("mag-order",Value(51)).asInt32();
127 
128  mag_vel_thres_up=config.check("mag-vel-thres-up",Value(0.04)).asFloat64();
129  mag_vel_thres_down=config.check("mag-vel-thres-down",Value(0.02)).asFloat64();
130  bias_gain=config.check("bias-gain",Value(0.001)).asFloat64();
131  verbose=config.check("verbose");
132 
133  gyroFilt.setOrder(gyro_order);
134  magFilt.setOrder(mag_order);
135  biasInt.setTs(bias_gain);
136  gyroBias.resize(3,0.0);
137  adaptGyroBias=false;
138 
139  m_period_ms=config.check("period",Value(20)).asInt32();
140 
141  if (name.at(0) != '/')
142  name = "/" +name;
143  ok &= bPort.open(name+"/bias:o");
144 
145  this->setPeriod(m_period_ms / 1000.0);
146 
147  if (!ok) {
148  yError()<<"imuFilter: failed to open the bias port";
149  return false;
150  }
151  return true;
152 
153 }
154 
156 {
157  bool ok = detachAll();
159  return ok;
160 }
161 
162 bool ImuFilter::attachAll(const yarp::dev::PolyDriverList &p) {
163 
165  return this->start();
166  }
167  else{
168  yError()<<"imuFilter: attach failed";
169  return false;
170  }
171 }
173  this->PeriodicThread::stop();
175 }
176 
177 bool ImuFilter::getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const
178 {
179  if (sens_index != 0)
180  {
181  yError() << "imuFilter: sens_index must be equal to 0 as there exists only one sensor";
182  return false;
183  }
184 
185  m_mutex.lock();
186  out = gyro;
187  timestamp = gyroTs;
188  m_mutex.unlock();
189  return true;
190 }
191 
192 } // namespace dev
193 } // namespace yarp
Basic element for adaptive polynomial fitting.
yarp::sig::Vector estimate()
Execute the algorithm upon the elements list, with the max deviation threshold given by D.
const yarp::sig::Vector & integrate(const yarp::sig::Vector &x)
Executes one-step integration of input vector.
Definition: pids.cpp:115
void setTs(const double _Ts)
Sets the sample time.
Definition: pids.cpp:96
virtual const yarp::sig::Vector & filt(const yarp::sig::Vector &u)
Performs filtering on the actual input.
Definition: filters.cpp:338
void setOrder(const size_t n)
Sets new filter order.
Definition: filters.cpp:315
bool close() override
Definition: ImuFilter.cpp:155
bool attachAll(const yarp::dev::PolyDriverList &p) override
Definition: ImuFilter.cpp:162
bool detachAll() override
Definition: ImuFilter.cpp:172
bool threadInit() override
Definition: ImuFilter.cpp:39
bool open(yarp::os::Searchable &config) override
Definition: ImuFilter.cpp:111
bool getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector &out, double &timestamp) const override
Definition: ImuFilter.cpp:177
void threadRelease() override
Definition: ImuFilter.cpp:108
void run() override
Definition: ImuFilter.cpp:42
bool attachAll(const yarp::dev::PolyDriverList &p) override
yarp::dev::IThreeAxisGyroscopes * proxyIGyro
yarp::dev::IThreeAxisMagnetometers * proxyIMagn
bool open(yarp::os::Searchable &config) override
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
Copyright (C) 2008 RobotCub Consortium.
out
Definition: sine.m:8