joy_dummy.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, UC Regents
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the University of California nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 #include <ros/ros.h>
00035 #include <sensor_msgs/Joy.h>
00036 #include <math.h>
00037 #include <signal.h>
00038 #include <termios.h>
00039 #include <stdio.h>
00040 #include <sys/select.h>
00041 class JoyDummy
00042 {
00043 private:
00044   ros::NodeHandle nh;
00045   ros::NodeHandle nh_priv;
00046 
00047   ros::Publisher joy_pub;
00048 
00049   ros::Timer publish_timer;
00050 
00051   sensor_msgs::Joy joy_msg;
00052 
00053   // Parameters
00054   double publish_rate; // [Hz] rate to republish Joy messages at
00055   double twiddle_period; // [s] period for 'twiddling' each axis
00056   std::string mode;
00057   bool go_operational;
00058 
00059   // Member vars
00060   ros::Time start_time;
00061   int kfd;
00062   struct termios cooked, raw;
00063 
00064 public:
00065   JoyDummy() :
00066     nh_priv("~"), publish_rate(20), twiddle_period(2.0), mode("twiddle"), kfd(0)
00067   {
00068     nh_priv.param("publish_rate", publish_rate, publish_rate);
00069     nh_priv.param("twiddle_period", twiddle_period, twiddle_period);
00070     nh_priv.param("mode", mode, mode);
00071     nh_priv.param("go_operational", go_operational, go_operational);
00072     joy_pub = nh.advertise<sensor_msgs::Joy> ("joy", 1);
00073 
00074     publish_timer = nh.createTimer(ros::Duration(1 / publish_rate), &JoyDummy::publishJoyCallback, this);
00075 
00076     joy_msg.axes.resize(10, 0);
00077     joy_msg.buttons.resize(10, 0);
00078 
00079     start_time = ros::Time::now();
00080 
00081     // get the console in raw mode
00082     tcgetattr(kfd, &cooked);
00083     memcpy(&raw, &cooked, sizeof(struct termios));
00084     raw.c_lflag &= ~(ICANON | ECHO);
00085     // Setting a new line, then end of file
00086     raw.c_cc[VEOL] = 1;
00087     raw.c_cc[VEOF] = 2;
00088     tcsetattr(kfd, TCSANOW, &raw);
00089 
00090     puts("Reading from keyboard");
00091     puts("---------------------------");
00092     puts("Number keys 1-9 map to joystick buttons");
00093     puts("Number key 0 toggles trigger");
00094 
00095   }
00096 
00097   ~JoyDummy()
00098   {
00099     tcsetattr(kfd, TCSANOW, &cooked);
00100   }
00101 
00102 private:
00103   int kbhit()
00104   {
00105     struct timeval tv = {0L, 0L};
00106     fd_set fds;
00107     FD_SET(kfd, &fds);
00108     return select(1, &fds, NULL, NULL, &tv);
00109   }
00110   int getch()
00111   {
00112     int r;
00113     unsigned char c;
00114     if ((r = read(0, &c, sizeof(c))) < 0)
00115     {
00116       return r;
00117     }
00118     else
00119     {
00120       return c;
00121     }
00122   }
00123   void publishJoyCallback(const ros::TimerEvent& e)
00124   {
00125     double t = (ros::Time::now() - start_time).toSec();
00126     double x;
00127     int ax;
00128     static double t_confirm = 0;
00129     static bool kb_trigger = false;
00130 
00131     joy_msg.axes.assign(10, 0);
00132     joy_msg.buttons.assign(10, 0);
00133 
00134     int c;
00135     if (kbhit())
00136     {
00137       c = getch();
00138       if (c > 48 and c <= 57)
00139       {
00140         joy_msg.buttons[c - 48] = 1;
00141         ROS_INFO_STREAM("Setting button: " << (c-48));
00142       }
00143       else if (c == 48)
00144       {
00145         kb_trigger = !kb_trigger;
00146         ROS_INFO_STREAM("Setting trigger: " << int(kb_trigger));
00147       }
00148       else
00149       {
00150         ROS_INFO_STREAM("Got character code: " << c);
00151       }
00152     }
00153     joy_msg.buttons[0] = int(kb_trigger);
00154 
00155     if (mode == "twiddle")
00156     {
00157       x = sin(t / twiddle_period * M_PI * 2);
00158       ax = int(floor(t / twiddle_period)) % 4;
00159       joy_msg.axes[3] = -1.0; // force throttle to end up low
00160       joy_msg.axes[ax] = x;
00161     }
00162     if (go_operational)
00163     {
00164       // Command go to operational:
00165       if (5.0 <= t && t <= 5.2)
00166       {
00167         joy_msg.buttons[2] = 1;
00168         t_confirm = 6.0;
00169       }
00170 
00171       // Command attitude mode:
00172       if (7.0 <= t && t <= 7.2)
00173       {
00174         joy_msg.buttons[2] = 1;
00175         t_confirm = 8.0;
00176       }
00177 
00178       // Confirm commands:
00179       if (t_confirm <= t && t <= t_confirm + 0.2)
00180       {
00181         joy_msg.buttons[8] = 1;
00182       }
00183       else if (t > t_confirm + 0.2)
00184       {
00185         t_confirm = 0;
00186       }
00187 
00188       if (t >= 10.0 && t < 20.0)
00189       {
00190         joy_msg.buttons[0] = 1;
00191       }
00192       else if (t >= 20.0)
00193       {
00194         joy_msg.buttons[0] = 0;
00195       }
00196     }
00197     sensor_msgs::Joy joy_copy = joy_msg;
00198     joy_pub.publish(joy_copy);
00199   }
00200 
00201 };
00202 
00203 int main(int argc, char** argv)
00204 {
00205   ros::init(argc, argv, "joy_dummy");
00206   JoyDummy joy_dummy;
00207 
00208   ros::spin();
00209 
00210   return 0;
00211 }


flyer_controller
Author(s): Patrick Bouffard
autogenerated on Sun Jan 5 2014 11:37:53