Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 PKG_NAME = 'art_teleop'
00011
00012
00013 import sys
00014 import math
00015 import Queue
00016
00017 import pilot_cmd
00018 import nav_estop
00019
00020
00021 import roslib;
00022 roslib.load_manifest(PKG_NAME)
00023 import rospy
00024
00025
00026 from art_msgs.msg import ArtVehicle
00027 from art_msgs.msg import Gear
00028 from art_msgs.msg import SteeringState
00029
00030
00031
00032 try:
00033 from sensor_msgs.msg import Joy
00034 except ImportError:
00035 from joy.msg import Joy
00036
00037
00038 from driver_base.msg import SensorLevels
00039 from dynamic_reconfigure.server import Server as ReconfigureServer
00040 import art_teleop.cfg.JoyConfig as JoyConfig
00041
00042 def clamp(minimum, value, maximum):
00043 "constrain value to the range [minimum .. maximum]"
00044 return max(minimum, min(value, maximum))
00045
00046 class JoyNode():
00047 "Vehicle joystick tele-operation node."
00048
00049 def __init__(self):
00050 "JoyNode constructor"
00051
00052
00053 self.run = 3
00054 self.suspend = 12
00055 self.estop = 13
00056
00057
00058 self.steer = 0
00059 self.drive = 4
00060 self.reverse = 6
00061 self.park = 7
00062 self.throttle = 18
00063 self.throttle_start = True
00064 self.brake = 19
00065 self.brake_start = True
00066 self.steeringQueue = Queue.Queue()
00067 self.counter = 0
00068
00069
00070 rospy.init_node('jaime_teleop')
00071 self.pilot = pilot_cmd.PilotCommand()
00072 self.steering = SteeringState()
00073 self.reconf_server = ReconfigureServer(JoyConfig, self.reconfigure)
00074 self.joy = rospy.Subscriber('joy', Joy, self.joyCallback)
00075
00076 def joyCallback(self, joy):
00077 "invoked every time a joystick message arrives"
00078 rospy.logdebug('joystick input:\n' + str(joy))
00079
00080
00081 if joy.buttons[self.estop]:
00082 rospy.logwarn('emergency stop')
00083 if self.use_navigator:
00084 self.nav.pause()
00085 else:
00086 self.pilot.halt()
00087 elif joy.buttons[self.suspend] and self.use_navigator:
00088 rospy.logwarn('suspend autonomous operation')
00089 self.nav.suspend()
00090 elif joy.buttons[self.run] and self.use_navigator:
00091 rospy.logwarn('start autonomous operation')
00092 self.nav.run()
00093
00094
00095 if joy.buttons[self.drive]:
00096 self.pilot.shift(Gear.Drive)
00097 rospy.loginfo('shifting to drive')
00098 elif joy.buttons[self.reverse]:
00099 self.pilot.shift(Gear.Reverse)
00100 rospy.loginfo('shifting to reverse')
00101 elif joy.buttons[self.park]:
00102 self.pilot.shift(Gear.Park)
00103 rospy.loginfo('shifting to park')
00104
00105
00106 self.setAngle(joy.axes[self.steer])
00107
00108
00109
00110 br = joy.axes[self.brake]
00111 th = joy.axes[self.throttle]
00112 rospy.logdebug('joystick brake, throttle: '
00113 + str(br) + ', ' + str(th))
00114
00115
00116
00117 if self.brake_start:
00118 if br == 0.0:
00119 br = 1.0
00120 else:
00121 self.brake_start = False
00122
00123 if self.throttle_start:
00124 if th == 0.0:
00125 th = 1.0
00126 else:
00127 self.throttle_start = False
00128
00129
00130 dv = 0.0
00131 if br < 1.0:
00132 dv = br - 1.0
00133 elif th < 1.0:
00134 dv = 1.0 - th
00135 self.pilot.accelerate(dv * self.config['max_accel'])
00136
00137 if self.nav.is_suspended():
00138 self.pilot.publish()
00139 else:
00140 rospy.logdebug('car running autonomously (command ignored)')
00141
00142 def reconfigure(self, config, level):
00143 "Dynamic reconfigure server callback."
00144 rospy.loginfo('Reconfigure callback, level ' + str(level))
00145 rospy.loginfo('New config ' + str(config))
00146
00147 if level & SensorLevels.RECONFIGURE_CLOSE:
00148
00149 self.use_navigator = config['use_navigator']
00150 rospy.loginfo('use navigator = ' + str(self.use_navigator))
00151
00152 self.nav = nav_estop.EstopNavigator(self.use_navigator)
00153
00154 self.pilot.reconfigure(config['limit_forward'],
00155 config['limit_reverse'])
00156
00157 self.config = config
00158 return config
00159
00160 def setAngle(self, turn):
00161 "set wheel angle"
00162
00163
00164
00165
00166
00167
00168
00169
00170 if(self.counter < 5):
00171 self.counter +=1
00172 self.steeringQueue.put(self.steering.angle/180)
00173 else:
00174
00175 oldVal = self.steeringQueue.get()
00176
00177 currentRate = (self.steering.angle/180 - oldVal)/.25
00178 limit = 2.0361 * math.pow(.72898, self.pilot.pstate.current.speed)
00179 rospy.logwarn(str(currentRate) + ' ' + str(limit))
00180
00181
00182
00183 if(math.fabs(currentRate > limit)):
00184 rospy.logwarn('Success')
00185 turn = limit*.25 + oldVal
00186
00187
00188 self.steeringQueue.put(turn)
00189
00190
00191
00192 self.pilot.steer(turn)
00193
00194 joynode = None
00195
00196 def main():
00197 global joynode
00198 joynode = JoyNode()
00199 rospy.loginfo('joystick vehicle controller starting')
00200 try:
00201 rospy.spin()
00202 except rospy.ROSInterruptException: pass
00203 rospy.loginfo('joystick vehicle controller finished')
00204
00205 if __name__ == '__main__':
00206
00207 sys.exit(main())