Go to the documentation of this file.00001 #include "cirkit_unit03_driver.hpp"
00002
00003
00004 #include <nav_msgs/Odometry.h>
00005
00006
00007 #include <iostream>
00008 #include <stdexcept>
00009
00010 cirkit::CirkitUnit03Driver::CirkitUnit03Driver(const std::string& imcs01_port, const ros::NodeHandle& nh)
00011 : nh_ {nh},
00012 rate_ {100},
00013 odom_pub_ {nh_.advertise<nav_msgs::Odometry>("/odom", 1)},
00014 steer_pub_ {nh_.advertise<geometry_msgs::Twist>("/steer_ctrl", 1)},
00015 cmd_vel_sub_ {nh_.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, &cirkit::CirkitUnit03Driver::cmdVelReceived, this)},
00016 cirkit_unit03_ {imcs01_port, 0},
00017 odom_broadcaster_ {},
00018 imcs01_port_ {imcs01_port},
00019 current_time_ {},
00020 last_time_ {},
00021 steer_dir_ {}
00022 {
00023 double pulse_rate {40.0};
00024 double geer_rate {33.0};
00025 double wheel_diameter_right {0.275};
00026 double wheel_diameter_left {0.275};
00027 double tred_width {0.595};
00028 ros::NodeHandle n {"~"};
00029 n.param("pulse_rate", pulse_rate, pulse_rate);
00030 n.param("geer_rate", geer_rate, geer_rate);
00031 n.param("wheel_diameter_right", wheel_diameter_right, wheel_diameter_right);
00032 n.param("wheel_diameter_left", wheel_diameter_left, wheel_diameter_left);
00033 n.param("tred_width", tred_width, tred_width);
00034
00035 cirkit_unit03_.setParams(pulse_rate, geer_rate, wheel_diameter_right, wheel_diameter_left, tred_width);
00036
00037 resetCommunication();
00038 }
00039
00040 cirkit::CirkitUnit03Driver::~CirkitUnit03Driver()
00041 {
00042 cirkit_unit03_.closeSerialPort();
00043 }
00044
00045 void cirkit::CirkitUnit03Driver::resetCommunication()
00046 {
00047 if (cirkit_unit03_.openSerialPort() == 0)
00048 {
00049 ROS_INFO("Connected to cirkit unit03.");
00050 cirkit_unit03_.driveDirect(0, 0);
00051 }
00052 else
00053 {
00054 ROS_FATAL("Could not connect to cirkit unit03.");
00055 throw std::runtime_error {"Could not connect to cirkit unit03"};
00056 }
00057
00058 cirkit_unit03_.resetOdometry();
00059 cirkit_unit03_.setOdometry(0, 0, 0);
00060 }
00061
00062 void cirkit::CirkitUnit03Driver::run()
00063 {
00064 double last_x, last_y, last_yaw;
00065 double vel_x, vel_y, vel_yaw;
00066 double dt;
00067
00068 while (nh_.ok())
00069 {
00070 current_time_ = ros::Time::now();
00071 last_x = cirkit_unit03_.odometry_x_;
00072 last_y = cirkit_unit03_.odometry_y_;
00073 last_yaw = cirkit_unit03_.odometry_yaw_;
00074 if (cirkit_unit03_.getEncoderPacket() == -1) ROS_ERROR("Could not retrieve encoder packet.");
00075 else cirkit_unit03_.calculateOdometry();
00076 dt = (current_time_ - last_time_).toSec();
00077 vel_x = (cirkit_unit03_.odometry_x_ - last_x)/dt;
00078 vel_y = (cirkit_unit03_.odometry_y_ - last_y)/dt;
00079 vel_yaw = (cirkit_unit03_.odometry_yaw_ - last_yaw)/dt;
00080
00081 geometry_msgs::Quaternion odom_quat {tf::createQuaternionMsgFromYaw(cirkit_unit03_.odometry_yaw_)};
00082 geometry_msgs::TransformStamped odom_trans;
00083 odom_trans.header.stamp = current_time_;
00084 odom_trans.header.frame_id = "odom";
00085 odom_trans.child_frame_id = "base_link";
00086
00087 odom_trans.transform.translation.x = cirkit_unit03_.odometry_x_;
00088 odom_trans.transform.translation.y = cirkit_unit03_.odometry_y_;
00089 odom_trans.transform.translation.z = 0.0;
00090 odom_trans.transform.rotation = odom_quat;
00091
00092 odom_broadcaster_.sendTransform(odom_trans);
00093
00094 nav_msgs::Odometry odom;
00095 odom.header.stamp = current_time_;
00096 odom.header.frame_id = "odom";
00097
00098
00099 odom.pose.pose.position.x = cirkit_unit03_.odometry_x_;
00100 odom.pose.pose.position.y = cirkit_unit03_.odometry_y_;
00101 odom.pose.pose.position.z = 0.0;
00102 odom.pose.pose.orientation = odom_quat;
00103
00104
00105 odom.child_frame_id = "base_link";
00106 odom.twist.twist.linear.x = vel_x;
00107 odom.twist.twist.linear.y = vel_y;
00108 odom.twist.twist.angular.z = vel_yaw;
00109
00110
00111 odom_pub_.publish(odom);
00112
00113 ros::spinOnce();
00114 rate_.sleep();
00115 }
00116 }
00117
00118 void cirkit::CirkitUnit03Driver::cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
00119 {
00120 steer_dir_ = cirkit_unit03_.drive(cmd_vel->linear.x, cmd_vel->angular.z);
00121 steer_pub_.publish(steer_dir_);
00122 }