Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <iostream>
00035 #include <Eigen/Dense>
00036 #include <ros/ros.h>
00037 #include <graft/GraftParameterManager.h>
00038 #include <graft/GraftSensor.h>
00039 #include <graft/GraftOdometryTopic.h>
00040 #include <graft/GraftImuTopic.h>
00041 #include <graft/GraftUKFVelocity.h>
00042 #include <graft/GraftState.h>
00043 #include <tf/transform_broadcaster.h>
00044
00045 GraftUKFVelocity ukfv;
00046
00047 ros::Publisher state_pub;
00048 ros::Publisher odom_pub;
00049
00050 nav_msgs::Odometry odom_;
00051
00052
00053 bool publish_tf_;
00054 boost::shared_ptr<tf::TransformBroadcaster> broadcaster_;
00055
00056 std::string parent_frame_id_;
00057 std::string child_frame_id_;
00058
00059 void publishTF(const nav_msgs::Odometry& msg){
00060 geometry_msgs::TransformStamped tf;
00061 tf.header.stamp = msg.header.stamp;
00062 tf.header.frame_id = msg.header.frame_id;
00063 tf.child_frame_id = msg.child_frame_id;
00064
00065 tf.transform.translation.x = msg.pose.pose.position.x;
00066 tf.transform.translation.y = msg.pose.pose.position.y;
00067 tf.transform.translation.z = msg.pose.pose.position.z;
00068 tf.transform.rotation = msg.pose.pose.orientation;
00069
00070 broadcaster_->sendTransform(tf);
00071 }
00072
00073 void timer_callback(const ros::TimerEvent& event){
00074 double dt = ukfv.predictAndUpdate();
00075
00076 graft::GraftState state = *ukfv.getMessageFromState();
00077 state.header.stamp = ros::Time::now();
00078 state_pub.publish(state);
00079
00080 odom_.header.stamp = ros::Time::now();
00081 odom_.header.frame_id = parent_frame_id_;
00082 odom_.child_frame_id = child_frame_id_;
00083 odom_.twist.twist.linear.x = state.twist.linear.x;
00084 odom_.twist.twist.linear.y = state.twist.linear.y;
00085 odom_.twist.twist.angular.z = state.twist.angular.z;
00086
00087
00088 double diff = pow(odom_.pose.pose.orientation.w, 2.0)-pow(odom_.pose.pose.orientation.z, 2.0);
00089 double mult = 2.0*odom_.pose.pose.orientation.w*odom_.pose.pose.orientation.z;
00090 double theta = atan2(mult, diff);
00091 if(std::abs(odom_.twist.twist.angular.z) < 0.00001){
00092 odom_.pose.pose.position.x += odom_.twist.twist.linear.x*dt*cos(theta)-odom_.twist.twist.linear.y*dt*sin(theta);
00093 odom_.pose.pose.position.y += odom_.twist.twist.linear.x*dt*sin(theta)+odom_.twist.twist.linear.y*dt*cos(theta);
00094 } else {
00095 double curvature_x = odom_.twist.twist.linear.x/odom_.twist.twist.angular.z;
00096 double curvature_y = odom_.twist.twist.linear.y/odom_.twist.twist.angular.z;
00097 double new_theta = theta + odom_.twist.twist.angular.z*dt;
00098
00099 odom_.pose.pose.position.x += -curvature_x*sin(theta) + curvature_x*sin(new_theta);
00100 odom_.pose.pose.position.x += -curvature_y*cos(theta) + curvature_y*cos(new_theta);
00101 odom_.pose.pose.position.y += curvature_x*cos(theta) - curvature_x*cos(new_theta);
00102 odom_.pose.pose.position.y += -curvature_y*sin(theta) + curvature_y*sin(new_theta);
00103 theta = new_theta;
00104 }
00105 odom_.pose.pose.orientation.z = sin(theta/2.0);
00106 odom_.pose.pose.orientation.w = cos(theta/2.0);
00107 odom_pub.publish(odom_);
00108 if(publish_tf_){
00109 publishTF(odom_);
00110 }
00111 }
00112
00113 int main(int argc, char **argv)
00114 {
00115 ros::init(argc, argv, "graft_ukf_velocity");
00116 ros::NodeHandle n;
00117 ros::NodeHandle pnh("~");
00118 state_pub = pnh.advertise<graft::GraftState>("state", 5);
00119 odom_pub = n.advertise<nav_msgs::Odometry>("odom_combined", 5);
00120
00121
00122 std::vector<boost::shared_ptr<GraftSensor> > topics;
00123 std::vector<ros::Subscriber> subs;
00124 GraftParameterManager manager(n, pnh);
00125 manager.loadParameters(topics, subs);
00126
00127 publish_tf_ = manager.getPublishTF();
00128
00129 parent_frame_id_ = manager.getParentFrameID();
00130 child_frame_id_ = manager.getChildFrameID();
00131
00132
00133 std::vector<double> initial_covariance = manager.getInitialCovariance();
00134 std::vector<double> Q = manager.getProcessNoise();
00135 ukfv.setAlpha(manager.getAlpha());
00136 ukfv.setKappa(manager.getKappa());
00137 ukfv.setBeta(manager.getBeta());
00138 ukfv.setInitialCovariance(initial_covariance);
00139 ukfv.setProcessNoise(Q);
00140 ukfv.setTopics(topics);
00141
00142 odom_.pose.pose.position.x = 0.0;
00143 odom_.pose.pose.position.y = 0.0;
00144 odom_.pose.pose.position.z = 0.0;
00145
00146 odom_.pose.pose.orientation.w = 1.0;
00147 odom_.pose.pose.orientation.x = 0.0;
00148 odom_.pose.pose.orientation.y = 0.0;
00149 odom_.pose.pose.orientation.z = 0.0;
00150
00151 odom_.twist.twist.linear.x = 0.0;
00152 odom_.twist.twist.linear.y = 0.0;
00153 odom_.twist.twist.linear.z = 0.0;
00154 odom_.twist.twist.angular.x = 0.0;
00155 odom_.twist.twist.angular.y = 0.0;
00156 odom_.twist.twist.angular.z = 0.0;
00157
00158
00159 broadcaster_.reset(new tf::TransformBroadcaster());
00160
00161
00162 ros::Timer timer = n.createTimer(ros::Duration(1.0/manager.getUpdateRate()), timer_callback);
00163
00164
00165 ros::spin();
00166 }