XBox360RemoteControlI.H

00001 #include "Component/ModelManager.H"
00002 #include "Component/OptionManager.H"
00003 
00004 #include "Component/ModelComponent.H"
00005 #include "Component/ModelParam.H"
00006 #include "Media/FrameSeries.H"
00007 #include "Transport/FrameInfo.H"
00008 #include "Raster/GenericFrame.H"
00009 #include "Image/Image.H"
00010 #include "GUI/XWinManaged.H"
00011 #include "GUI/ImageDisplayStream.H"
00012 #include "Image/Image.H"
00013 #include "Image/Pixels.H"
00014 #include "Robots/RobotBrain/RobotBrainComponent.H"
00015 
00016 #include "Ice/RobotBrainObjects.ice.H"
00017 #include "Ice/RobotSimEvents.ice.H"
00018 #include "Ice/IceImageUtils.H"
00019 #include <IceUtil/Thread.h>
00020 #include <map>
00021 
00022 #include "Devices/JoyStick.H"
00023 
00024 #ifndef XBOX360REMOTECONTROLI_H_
00025 #define XBOX360REMOTECONTROLI_H_
00026 
00027 #define MAX_JS_AXIS_VAL 32767.0
00028 #define JS_DEAD_ZONE 15
00029 #define JS_AXIS_MAX 100
00030 
00031 class TestJoyStickListener;
00032 
00033 namespace XBox360RemoteControl
00034 {
00035         struct ControlAxis
00036         {
00037                 const static int BTN = 0; //button
00038                 const static int JSTK = 1; //joystick
00039                 const static int TRGR = 2; //trigger
00040                 const static int NONE = -9999;
00041 
00042                 struct Btn
00043                 {
00044                         static int Id;
00045                         const static int mType = BTN;
00046                 };
00047 
00048                 struct Axis
00049                 {
00050                         static int Id;
00051                         const static int mType = JSTK;
00052                 };
00053         };
00054 
00055         struct Keys //store keys for specific actions and labels
00056         {
00057                 struct Btns
00058                 {
00059                         enum Ids
00060                         {
00061                                 L_BUMPER,
00062                                 R_BUMPER,
00063                                 BACK,
00064                                 START,
00065                                 CENTER,
00066                                 L_JOYSTICK,
00067                                 R_JOYSTICK,
00068                                 X,
00069                                 Y,
00070                                 A,
00071                                 B
00072                         };
00073                 };
00074 
00075                 struct Axes
00076                 {
00077                         enum
00078                         {
00079                                 L_TRIGGER,
00080                                 R_TRIGGER,
00081                                 L_JOYSTICK_X,
00082                                 L_JOYSTICK_Y,
00083                                 R_JOYSTICK_X,
00084                                 R_JOYSTICK_Y,
00085                                 DPAD_X, //you'd think it's a button, but it's actually a joystick
00086                                 DPAD_Y
00087                         };
00088                 };
00089 
00090                 struct Actions
00091                 {
00092                         static std::map<int, std::string> toString;
00093                         static std::map<std::string, int> toInt;
00094 
00095                         enum Ids
00096                         {
00097                                 AXIS_INVERT, DIVE, SURFACE, STRAFE, SPEED, HEADING, ARM_NEXT_DEV, FIRE_DEV, NONE
00098                         };
00099 
00100                         static std::map<int, std::string> populateMappingToString()
00101                         {
00102                                 std::map<int, std::string> theResult;
00103                                 theResult[AXIS_INVERT] = "AXIS_INVERT";
00104                                 theResult[DIVE] = "DIVE";
00105                                 theResult[SURFACE] = "SURFACE";
00106                                 theResult[STRAFE] = "STRAFE";
00107                                 theResult[SPEED] = "SPEED";
00108                                 theResult[HEADING] = "HEADING";
00109                                 theResult[ARM_NEXT_DEV] = "ARM_NEXT_DEV";
00110                                 theResult[FIRE_DEV] = "FIRE_DEV";
00111                                 return theResult;
00112                         }
00113                 };
00114 
00115                 template<class _T1, class _T2>
00116                 static std::map<_T2, _T1> populateInverseMapping(std::map<_T1, _T2> m)
00117                 {
00118                         std::map<_T2, _T1> theResult;
00119                         class std::map<_T1, _T2>::iterator it;
00120                         for(it = m.begin(); it != m.end(); it ++)
00121                         {
00122                                 theResult[it->second] = it->first;
00123                         }
00124                         return theResult;
00125                 }
00126         };
00127 }
00128 
00129 class XBox360RemoteControlI: public RobotBrainComponent
00130 {
00131 public:
00132 
00133         XBox360RemoteControlI();
00134 
00135         XBox360RemoteControlI(int id, OptionManager& mgr,
00136                         const std::string& descrName = "XBox360RemoteControl",
00137                         const std::string& tagName = "XBox360RemoteControl");
00138 
00139         ~XBox360RemoteControlI();
00140 
00141         virtual void evolve();
00142 
00143         //!Get a message
00144         virtual void updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00145                         const Ice::Current&);
00146 
00147         virtual void registerTopics();
00148 
00149         void calibrate();
00150         void updateSetBtn(int btn);
00151         void updateSetAxis(int axis);
00152         void updateSetAxisInversion();
00153         bool isEnabled()
00154         {
00155                 return itsJS.get()->joystickPlugged();
00156         }
00157         bool isCalibrated()
00158         {
00159                 return itsCalibrated;
00160         }
00161 
00162         std::map<int, int> itsTypeMappings; //indicates whether each axis is a button or a joystick
00163         std::map<int, int> itsActionIds; //maps axis indices to key names for actions
00164         std::map<int, int> itsAxisIndices; //maps key names for actions to axis indices
00165         std::map<int, int> itsInversionMappings; //maps axis indices to inversion values; 1 = normal, -1 = inverted
00166 
00167         //std::map<int, int> itsAxisIds; //maps action ids to axis ids, not useful right now
00168         //std::map<int, int> itsBtnIds; //maps action ids to button ids, not useful right now
00169 
00170 private:
00171         int selectionType;
00172         int itsAxisInversionBtn;
00173         bool itsCalibrated;
00174         int itsSetBtn; //set each time a btn is pressed, holds the index of that btn
00175         int itsSetAxis; //set each time an axis is set to +/- max, used to determine which axis is being selected for use
00176         bool itsSetAxisInvert; //set each time btn A is pressed (indicates last axis should be inverted)
00177         IceUtil::Mutex itsSetBtnMutex;
00178         IceUtil::Mutex itsSetAxisMutex;
00179         IceUtil::Mutex itsSetAxisInvertMutex;
00180 
00181         //OModelParam<std::int>              itsJoystickDisable;
00182 
00183 #ifdef HAVE_LINUX_JOYSTICK_H
00184         //JoyStick itsJSReal;
00185         nub::soft_ref<JoyStick> itsJS;
00186         rutz::shared_ptr<TestJoyStickListener> lis;
00187         rutz::shared_ptr<JoyStickListener> lis2;
00188 #endif
00189 };
00190 
00191 #ifdef HAVE_LINUX_JOYSTICK_H
00192 
00193 //! A simple joystick listener
00194 class TestJoyStickListener : public JoyStickListener
00195 {
00196 public:
00197         TestJoyStickListener(rutz::shared_ptr<XBox360RemoteControlI> remote)
00198         {       itsRemote = remote;}
00199 
00200         virtual ~TestJoyStickListener()
00201         {}
00202 
00203         virtual void axis(const uint num, const int16 val)
00204         {
00205                 //int invert = 1; //1 is normal, -1 is inverted
00206                 RobotSimEvents::JoyStickControlMessagePtr msg = new RobotSimEvents::JoyStickControlMessage;
00207                 if(itsRemote->itsActionIds.find(num) != itsRemote->itsActionIds.end())
00208                 {
00209                         msg->axisName = XBox360RemoteControl::Keys::Actions::toString[itsRemote->itsActionIds[num]];
00210                         //msg->axis = itsRemote->itsActionIds[num]; //fetch the enum action mapping
00211                 }
00212                 else
00213                 {
00214                         msg->axisName = "AXIS_NOT_BOUND";
00215                 }
00216 
00217                 msg->axis = num;
00218                 msg->axisVal = (int)(float(val)/MAX_JS_AXIS_VAL * 100.0);
00219 
00220                 // make sure value is outside of dead zone
00221                 if(abs(msg->axisVal) < JS_DEAD_ZONE)
00222                 msg->axisVal = 0;
00223                 else if(abs(msg->axisVal) > JS_AXIS_MAX &&
00224                                 msg->axis == 1)
00225                 {
00226                         if(msg->axisVal > 0)
00227                         msg->axisVal = JS_AXIS_MAX;
00228                         else
00229                         msg->axisVal = JS_AXIS_MAX * -1;
00230                 }
00231 
00232                 if(msg->axisVal == 100 || msg->axisVal == -100)
00233                 {
00234                         //invert = msg->axisVal / 100;
00235                         itsRemote->updateSetAxis(msg->axis);
00236                 }
00237 
00238                 if(itsRemote->itsInversionMappings.find(num) != itsRemote->itsInversionMappings.end() && itsRemote->itsInversionMappings[num] != 0)
00239                 {
00240                         msg->axisVal *= itsRemote->itsInversionMappings[num]; //apply possible inversion to the axis
00241                 }
00242 
00243                 msg->button = -1;
00244                 msg->butVal = 0;
00245 
00246                 if(msg->axisVal != 0)
00247                 {
00248                         //LINFO("Axis[%s] = %d", msg->axisName.c_str(), msg->axisVal);
00249                 }
00250 
00251                 if(itsRemote->isEnabled() && itsRemote->isCalibrated())
00252                 {
00253                         itsRemote->publish("XBox360RemoteControlMessageTopic", msg);
00254                 }
00255         }
00256 
00257         virtual void button(const uint num, const bool state)
00258         {
00259                 //LINFO("button: %d\n", num);
00260 
00261                 if(state && itsRemote->itsActionIds.find(-num-1) != itsRemote->itsActionIds.end() && itsRemote->itsActionIds[-num-1] == XBox360RemoteControl::Keys::Actions::AXIS_INVERT)
00262                 {
00263                         itsRemote->updateSetAxisInversion();
00264                 }
00265                 RobotSimEvents::JoyStickControlMessagePtr msg = new RobotSimEvents::JoyStickControlMessage;
00266                 msg->axis = -1;
00267                 msg->axisVal = 0;
00268                 if(itsRemote->itsTypeMappings.find(-num-1) != itsRemote->itsTypeMappings.end() && itsRemote->itsTypeMappings[-num-1] == XBox360RemoteControl::ControlAxis::BTN)
00269                 {
00270                         msg->axisName = XBox360RemoteControl::Keys::Actions::toString[itsRemote->itsActionIds[-num-1]];
00271                         msg->axis = -num-1;
00272                         msg->axisVal = state ? 100 * itsRemote->itsInversionMappings[-num-1] : 0;
00273                 }
00274                 msg->button = num;
00275                 msg->butVal = state;
00276                 if(state)
00277                 {
00278                         itsRemote->updateSetBtn(num);
00279                 }
00280                 else
00281                 {
00282                         //itsRemote->updateSetBtn(XBox360RemoteControl::ControlAxis::NONE);
00283                 }
00284                 //LINFO("Button[%d] = %d",msg->button, msg->butVal);
00285                 if(itsRemote->isEnabled() && itsRemote->isCalibrated())
00286                 {
00287                         itsRemote->publish("XBox360RemoteControlMessageTopic", msg);
00288                 }
00289         }
00290 
00291         rutz::shared_ptr<XBox360RemoteControlI> itsRemote;
00292 };
00293 
00294 #endif
00295 
00296 #endif //XBOX360REMOTECONTROLI_H_
Generated on Sun May 8 08:06:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3