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_