iCub-main
Loading...
Searching...
No Matches
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
26using namespace std;
27using namespace yarp::os;
28using namespace yarp::sig;
29
30namespace yarp {
31namespace dev {
32
33ImuFilter::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
111bool 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
162bool 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
177bool 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
bool attachAll(const yarp::dev::PolyDriverList &p) override
bool detachAll() override
bool threadInit() override
Definition ImuFilter.cpp:39
bool open(yarp::os::Searchable &config) override
bool getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector &out, double &timestamp) const override
void threadRelease() override
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
Copyright (C) 2008 RobotCub Consortium.
out
Definition sine.m:8