ethzasl-msf - Modular Sensor Fusion
Time delay compensated single and multi sensor fusion framework based on an EKF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
position_sensormanager.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2013 Simon Lynen, ASL, ETH Zurich, Switzerland
3  * You can contact the author at <slynen at ethz dot ch>
4  * Copyright (C) 2011-2012 Stephan Weiss, ASL, ETH Zurich, Switzerland
5  * You can contact the author at <stephan dot weiss at ieee dot org>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 #ifndef POSITION_MEASUREMENTMANAGER_H
20 #define POSITION_MEASUREMENTMANAGER_H
21 
22 #include <ros/ros.h>
23 
24 #include <msf_core/msf_core.h>
27 #include "msf_statedef.hpp"
28 #include <msf_updates/position_sensor_handler/position_sensorhandler.h>
29 #include <msf_updates/position_sensor_handler/position_measurement.h>
30 #include <msf_updates/SinglePositionSensorConfig.h>
31 
32 namespace msf_position_sensor {
33 
34 typedef msf_updates::SinglePositionSensorConfig Config_T;
35 typedef dynamic_reconfigure::Server<Config_T> ReconfigureServer;
36 typedef shared_ptr<ReconfigureServer> ReconfigureServerPtr;
37 
39  msf_updates::EKFState> {
40  typedef PositionSensorHandler<
41  msf_updates::position_measurement::PositionMeasurement,
43  friend class PositionSensorHandler<
44  msf_updates::position_measurement::PositionMeasurement,
46  public:
50 
52  ros::NodeHandle pnh = ros::NodeHandle("~/position_sensor")) {
53  imu_handler_.reset(
55  "imu_handler"));
56 
57  position_handler_.reset(
58  new PositionSensorHandler_T(*this, "", "position_sensor"));
60 
61  reconf_server_.reset(new ReconfigureServer(pnh));
62  ReconfigureServer::CallbackType f = boost::bind(
63  &PositionSensorManager::config, this, _1, _2);
64  reconf_server_->setCallback(f);
65  }
67  }
68 
69  virtual const Config_T& getcfg() {
70  return config_;
71  }
72 
73  private:
74  shared_ptr<msf_core::IMUHandler_ROS<msf_updates::EKFState> > imu_handler_;
75  shared_ptr<PositionSensorHandler_T> position_handler_;
76 
79 
83  virtual void config(Config_T &config, uint32_t level) {
84  config_ = config;
85  position_handler_->setNoises(config.position_noise_meas);
86  position_handler_->setDelay(config.position_delay);
87  if ((level & msf_updates::SinglePositionSensor_INIT_FILTER)
88  && config.core_init_filter == true) {
89  init(1.0);
90  config.core_init_filter = false;
91  }
92  }
93 
94  void init(double scale) const {
95  if (scale < 0.001) {
96  MSF_WARN_STREAM("init scale is "<<scale<<" correcting to 1");
97  scale = 1;
98  }
99 
100  Eigen::Matrix<double, 3, 1> p, v, b_w, b_a, g, w_m, a_m, p_ip, p_vc;
101  Eigen::Quaternion<double> q;
103 
104  // Init values.
105  g << 0, 0, 9.81;
106  b_w << 0, 0, 0;
107  b_a << 0, 0, 0;
108 
109  v << 0, 0, 0;
110  w_m << 0, 0, 0;
111  a_m = g;
112 
113  // Set the initial yaw alignment of body to world (the frame in which the
114  // position sensor measures).
115  double yawinit = config_.position_yaw_init / 180 * M_PI;
116  Eigen::Quaterniond yawq(cos(yawinit / 2), 0, 0, sin(yawinit / 2));
117  yawq.normalize();
118 
119  q = yawq;
120 
121  P.setZero(); // Error state covariance; if zero, a default initialization
122  // in msf_core is used
123 
124  p_vc = position_handler_->getPositionMeasurement();
125 
126  MSF_INFO_STREAM("initial measurement pos:["<<p_vc.transpose()<<"] orientation: "<<STREAMQUAT(q));
127 
128  // check if we have already input from the measurement sensor
129  if (p_vc.norm() == 0)
131  "No measurements received yet to initialize position - using [0 0 0]");
132 
133  ros::NodeHandle pnh("~");
134  pnh.param("position_sensor/init/p_ip/x", p_ip[0], 0.0);
135  pnh.param("position_sensor/init/p_ip/y", p_ip[1], 0.0);
136  pnh.param("position_sensor/init/p_ip/z", p_ip[2], 0.0);
137 
138  // Calculate initial attitude and position based on sensor measurements.
139  p = p_vc - q.toRotationMatrix() * p_ip;
140 
141  //prepare init "measurement"
142  // True means that we will also set the initialsensor readings.
143  shared_ptr < msf_core::MSF_InitMeasurement<EKFState_T>
145 
146  meas->setStateInitValue < StateDefinition_T::p > (p);
147  meas->setStateInitValue < StateDefinition_T::v > (v);
148  meas->setStateInitValue < StateDefinition_T::q > (q);
149  meas->setStateInitValue < StateDefinition_T::b_w > (b_w);
150  meas->setStateInitValue < StateDefinition_T::b_a > (b_a);
151  meas->setStateInitValue < StateDefinition_T::p_ip > (p_ip);
152 
153  setP(meas->get_P()); // Call my set P function.
154  meas->get_w_m() = w_m;
155  meas->get_a_m() = a_m;
156  meas->time = ros::Time::now().toSec();
157 
158  // Call initialization in core.
159  msf_core_->init(meas);
160  }
161 
162  // Prior to this call, all states are initialized to zero/identity.
163  virtual void resetState(EKFState_T& state) const {
164  UNUSED(state);
165  }
166  virtual void initState(EKFState_T& state) const {
167  UNUSED(state);
168  }
169 
170  virtual void calculateQAuxiliaryStates(EKFState_T& state, double dt) const {
171  const msf_core::Vector3 npipv = msf_core::Vector3::Constant(
172  config_.position_noise_p_ip);
173 
174  // Compute the blockwise Q values and store them with the states,
175  //these then get copied by the core to the correct places in Qd.
177  (dt * npipv.cwiseProduct(npipv)).asDiagonal();
178  }
179 
180  virtual void setP(
181  Eigen::Matrix<double, EKFState_T::nErrorStatesAtCompileTime,
183  UNUSED(P);
184  // Nothing, we only use the simulated cov for the core plus diagonal for the
185  // rest.
186  }
187 
189  Eigen::Matrix<double, EKFState_T::nErrorStatesAtCompileTime, 1>& correction) const {
190  UNUSED(correction);
191  }
192 
193  virtual void sanityCheckCorrection(
194  EKFState_T& delaystate,
195  const EKFState_T& buffstate,
196  Eigen::Matrix<double, EKFState_T::nErrorStatesAtCompileTime, 1>& correction) const {
197  UNUSED(delaystate);
198  UNUSED(buffstate);
199  UNUSED(correction);
200  }
201 };
202 }
203 #endif /* POSITION_MEASUREMENTMANAGER_H */