spacenav_commander.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include <string>
00019 #include <ros/ros.h>
00020 #include <geometry_msgs/Twist.h>
00021 #include <geometry_msgs/TwistStamped.h>
00022 #include <sensor_msgs/Joy.h>
00023 
00024 #include <boost/thread/mutex.hpp>
00025 
00026 class SpacenavCommander
00027 {
00028 public:
00029     SpacenavCommander()
00030     {
00031         twist_spacenav_sub_ = nh_.subscribe("/spacenav/twist", 1, &SpacenavCommander::twistSpacenavCallback, this);
00032         joy_spacenav_sub_ = nh_.subscribe("/spacenav/joy", 1, &SpacenavCommander::joySpacenavCallback, this);
00033         twist_pub_ = nh_.advertise<geometry_msgs::TwistStamped> ("twist_controller/command_twist_stamped", 1);
00034 
00035         if (nh_.hasParam("root_frame"))
00036         {
00037             nh_.getParam("root_frame", root_frame_);
00038         }
00039         else
00040         {
00041             ROS_WARN("No 'root_frame' specified. Setting to 'base_link'!");
00042             root_frame_ = "base_link";
00043         }
00044         if (nh_.hasParam("chain_tip_link"))
00045         {
00046             nh_.getParam("chain_tip_link", tip_frame_);
00047         }
00048         else
00049         {
00050             ROS_ERROR("No 'chain_tip_link' specified. Using 'root_frame' instead!");
00051             tip_frame_ = root_frame_;
00052         }
00053 
00054         // could be made a parameter or even dynamically reconfigurable
00055         ros::NodeHandle nh_priv("~");
00056         nh_priv.param<double>("scaling_factor", scaling_factor_, 0.1);
00057         dead_man_enabled_ = false;
00058         frame_id_ = root_frame_;
00059 
00060         timer_ = nh_.createTimer(ros::Duration(0.01), &SpacenavCommander::timerCallback, this);  // guarantee 100Hz
00061         timer_.start();
00062     }
00063 
00064     ~SpacenavCommander()
00065     {
00066     }
00067 
00069     void joySpacenavCallback(const sensor_msgs::Joy::ConstPtr& msg)
00070     {
00071         boost::mutex::scoped_lock lock(mutex_);
00072 
00073         if (msg->buttons[0])  // dead man
00074         {
00075             dead_man_enabled_ = true;
00076         }
00077         else
00078         {
00079             // publish one last zero-twist
00080             if (dead_man_enabled_)
00081             {
00082                 geometry_msgs::TwistStamped ts;
00083                 ts.header.frame_id = root_frame_;
00084                 ts.header.stamp = ros::Time::now();
00085                 twist_pub_.publish(ts);
00086             }
00087             dead_man_enabled_ = false;
00088         }
00089 
00090         if (msg->buttons[1])  // root_frame/tip_frame selection
00091         {
00092             frame_id_ = root_frame_;
00093         }
00094         else
00095         {
00096             frame_id_ = tip_frame_;
00097         }
00098     }
00099 
00101     void twistSpacenavCallback(const geometry_msgs::Twist::ConstPtr& msg)
00102     {
00103         boost::mutex::scoped_lock lock(mutex_);
00104 
00105         ts_.twist.linear.x = scaling_factor_ * msg->linear.x;
00106         ts_.twist.linear.y = scaling_factor_ * msg->linear.y;
00107         ts_.twist.linear.z = scaling_factor_ * msg->linear.z;
00108         ts_.twist.angular.x = scaling_factor_ * msg->angular.x;
00109         ts_.twist.angular.y = scaling_factor_ * msg->angular.y;
00110         ts_.twist.angular.z = scaling_factor_ * msg->angular.z;
00111     }
00112 
00113     void timerCallback(const ros::TimerEvent&)
00114     {
00115         boost::mutex::scoped_lock lock(mutex_);
00116 
00117         if (dead_man_enabled_)
00118         {
00119             ts_.header.frame_id = frame_id_;
00120             ts_.header.stamp = ros::Time::now();
00121 
00122             twist_pub_.publish(ts_);
00123         }
00124     }
00125 
00126 private:
00127     ros::NodeHandle nh_;
00128     ros::Subscriber twist_spacenav_sub_;
00129     ros::Subscriber joy_spacenav_sub_;
00130     ros::Publisher twist_pub_;
00131     ros::Timer timer_;
00132 
00133     bool dead_man_enabled_;
00134     boost::mutex mutex_;
00135     double scaling_factor_;
00136     std::string root_frame_, tip_frame_, frame_id_;
00137     geometry_msgs::TwistStamped ts_;
00138 };
00139 
00140 
00141 int main(int argc, char **argv)
00142 {
00143     ros::init(argc, argv, "spacenav_commander");
00144     SpacenavCommander sc;
00145     ros::spin();
00146 }


cob_frame_tracker
Author(s): Felix Messmer
autogenerated on Thu Jun 6 2019 21:19:08