46 static const double EPS = 1e-5;
54 OdomEstimationNode::OdomEstimationNode()
55 : odom_active_(false),
59 odom_initializing_(false),
60 imu_initializing_(false),
61 vo_initializing_(false),
62 gps_initializing_(false),
67 odom_callback_counter_(0),
68 imu_callback_counter_(0),
69 vo_callback_counter_(0),
70 gps_callback_counter_(0),
87 nh_private.
param(
"freq", freq, 30.0);
104 pose_pub_ = nh_private.
advertise<geometry_msgs::PoseWithCovarianceStamped>(
"odom_combined", 10);
114 else ROS_DEBUG(
"Odom sensor will NOT be used");
121 else ROS_DEBUG(
"Imu sensor will NOT be used");
128 else ROS_DEBUG(
"VO sensor will NOT be used");
134 else ROS_DEBUG(
"GPS sensor will NOT be used");
186 for (
unsigned int i=0; i<6; i++)
187 for (
unsigned int j=0; j<6; j++)
197 ROS_INFO(
"Initializing Odom sensor");
204 else ROS_DEBUG(
"Waiting to activate Odom, because Odom measurements are still %f sec in the future.",
229 quaternionMsgToTF(imu->orientation, orientation);
231 for (
unsigned int i=0; i<3; i++)
232 for (
unsigned int j=0; j<3; j++)
241 ROS_WARN(
"Could not transform imu message from %s to %s. Imu will not be activated yet.", imu->header.frame_id.c_str(),
base_footprint_frame_.c_str());
243 ROS_DEBUG(
"Could not transform imu message from %s to %s. Imu will not be activated yet.", imu->header.frame_id.c_str(),
base_footprint_frame_.c_str());
254 SymmetricMatrix measNoiseImu_Cov(3); measNoiseImu_Cov = 0;
255 measNoiseImu_Cov(1,1) = pow(0.00017,2);
256 measNoiseImu_Cov(2,2) = pow(0.00017,2);
257 measNoiseImu_Cov(3,3) = pow(0.00017,2);
268 ROS_INFO(
"Initializing Imu sensor");
275 else ROS_DEBUG(
"Waiting to activate IMU, because IMU measurements are still %f sec in the future.",
300 poseMsgToTF(vo->pose.pose,
vo_meas_);
301 for (
unsigned int i=0; i<6; i++)
302 for (
unsigned int j=0; j<6; j++)
318 else ROS_DEBUG(
"Waiting to activate VO, because VO measurements are still %f sec in the future.",
327 << Rx <<
" " << Ry <<
" " << Rz << endl;
341 geometry_msgs::PoseWithCovariance gps_pose = gps->pose;
342 if (isnan(gps_pose.pose.position.z)){
345 gps_pose.pose.position.z = 0;
347 gps_pose.covariance[6*2 + 2] = std::numeric_limits<double>::max();
350 for (
unsigned int i=0; i<3; i++)
351 for (
unsigned int j=0; j<3; j++)
360 ROS_INFO(
"Initializing GPS sensor");
367 else ROS_DEBUG(
"Waiting to activate GPS, because GPS measurements are still %f sec in the future.",
387 if (diff > 1.0)
ROS_ERROR(
"Timestamps of odometry and imu are %f seconds apart.", diff);
397 ROS_INFO(
"Odom sensor not active any more");
402 ROS_INFO(
"Imu sensor not active any more");
407 ROS_INFO(
"VO sensor not active any more");
413 ROS_INFO(
"GPS sensor not active any more");
429 bool diagnostics =
true;
446 ColumnVector estimate;
450 for (
unsigned int i=1; i<=6; i++)
456 ROS_WARN(
"Robot pose ekf diagnostics discovered a potential problem");
466 ROS_INFO(
"Kalman filter initialized with gps and imu measurement");
473 ROS_INFO(
"Kalman filter initialized with gps and odometry measurement");
480 ROS_INFO(
"Kalman filter initialized with gps and visual odometry measurement");
484 ROS_INFO(
"Kalman filter initialized with odom measurement");
488 ROS_INFO(
"Kalman filter initialized with vo measurement");
497 ss <<
"Input:" << endl;
498 ss <<
" * Odometry sensor" << endl;
499 ss <<
" - is ";
if (!
odom_used_) ss <<
"NOT "; ss <<
"used" << endl;
500 ss <<
" - is ";
if (!
odom_active_) ss <<
"NOT "; ss <<
"active" << endl;
503 ss <<
" * IMU sensor" << endl;
504 ss <<
" - is ";
if (!
imu_used_) ss <<
"NOT "; ss <<
"used" << endl;
505 ss <<
" - is ";
if (!
imu_active_) ss <<
"NOT "; ss <<
"active" << endl;
508 ss <<
" * Visual Odometry sensor" << endl;
509 ss <<
" - is ";
if (!
vo_used_) ss <<
"NOT "; ss <<
"used" << endl;
510 ss <<
" - is ";
if (!
vo_active_) ss <<
"NOT "; ss <<
"active" << endl;
513 ss <<
" * GPS sensor" << endl;
514 ss <<
" - is ";
if (!
gps_used_) ss <<
"NOT "; ss <<
"used" << endl;
515 ss <<
" - is ";
if (!
gps_active_) ss <<
"NOT "; ss <<
"active" << endl;
518 ss <<
"Output:" << endl;
519 ss <<
" * Robot pose ekf filter" << endl;
523 resp.status = ss.str();
538 int main(
int argc,
char **argv)
void spin(const ros::TimerEvent &e)
the mail filter loop that will be called periodically
OdomEstimation my_filter_
std::string getTopic() const
std::string getPrefixParam(ros::NodeHandle &nh)
virtual ~OdomEstimationNode()
destructor
unsigned int vo_callback_counter_
MatrixWrapper::SymmetricMatrix odom_covariance_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
unsigned int imu_callback_counter_
std::string base_footprint_frame_
bool getStatus(robot_pose_ekf::GetStatus::Request &req, robot_pose_ekf::GetStatus::Response &resp)
get the status of the filter
void initialize(const tf::Transform &prior, const ros::Time &time)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
geometry_msgs::PoseWithCovarianceStamped output_
ros::Time odom_init_stamp_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void getEulerYPR(tfScalar &yaw, tfScalar &pitch, tfScalar &roll, unsigned int solution_number=1) const
void odomCallback(const OdomConstPtr &odom)
callback function for odo data
MatrixWrapper::SymmetricMatrix vo_covariance_
tf::TransformBroadcaster odom_broadcaster_
void voCallback(const VoConstPtr &vo)
callback function for vo data
std::string resolve(const std::string &prefix, const std::string &frame_name)
void imuCallback(const ImuConstPtr &imu)
callback function for imu data
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
static void quaternionMsgToTF(const geometry_msgs::Quaternion &msg, Quaternion &bt)
MatrixWrapper::SymmetricMatrix imu_covariance_
bool update(bool odom_active, bool imu_active, bool gps_active, bool vo_active, const ros::Time &filter_time, bool &diagnostics_res)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Time gps_init_stamp_
void addMeasurement(const tf::StampedTransform &meas)
unsigned int ekf_sent_counter_
std::string getTopic() const
ros::Subscriber odom_sub_
#define ROS_INFO_STREAM(args)
tf::TransformListener robot_state_
unsigned int gps_callback_counter_
void setBaseFootprintFrame(const std::string &base_frame)
ros::ServiceServer state_srv_
ros::Time imu_init_stamp_
MatrixWrapper::SymmetricMatrix gps_covariance_
void gpsCallback(const GpsConstPtr &gps)
callback function for vo data
void setOutputFrame(const std::string &output_frame)
std::string output_frame_
void getEstimate(MatrixWrapper::ColumnVector &estimate)
unsigned int odom_callback_counter_
int main(int argc, char **argv)