$search
00001 #!/usr/bin/python 00002 import roslib; roslib.load_manifest('irobot_create_2_1') 00003 import rospy 00004 from time import sleep 00005 from irobot import Create 00006 from threading import Thread 00007 from math import sin,cos,pi 00008 from datetime import datetime 00009 00010 from geometry_msgs.msg import Quaternion 00011 from geometry_msgs.msg import Twist 00012 from nav_msgs.msg import Odometry 00013 from tf.broadcaster import TransformBroadcaster 00014 00015 from irobot_create_2_1.msg import SensorPacket 00016 from irobot_create_2_1.srv import * 00017 00018 class CreateDriver: 00019 def __init__(self): 00020 port = rospy.get_param('/brown/irobot_create_2_1/port', "/dev/ttyUSB0") 00021 self.autodock = rospy.get_param('/brown/irobot_create_2_1/autodock', 0.0) 00022 self.create = Create(port) 00023 self.packetPub = rospy.Publisher('sensorPacket', SensorPacket) 00024 self.odomPub = rospy.Publisher('odom',Odometry) 00025 self.odomBroadcaster = TransformBroadcaster() 00026 self.fields = ['wheeldropCaster','wheeldropLeft','wheeldropRight','bumpLeft','bumpRight','wall','cliffLeft','cliffFronLeft','cliffFrontRight','cliffRight','virtualWall','infraredByte','advance','play','distance','angle','chargingState','voltage','current','batteryTemperature','batteryCharge','batteryCapacity','wallSignal','cliffLeftSignal','cliffFrontLeftSignal','cliffFrontRightSignal','cliffRightSignal','homeBase','internalCharger','songNumber','songPlaying'] 00027 self.then = datetime.now() 00028 self.x = 0 00029 self.y = 0 00030 self.th = 0 00031 self.create.update = self.sense 00032 self.docking = False 00033 00034 def start(self): 00035 self.create.start() 00036 self.then = datetime.now() 00037 00038 def stop(self): 00039 self.create.stop() 00040 00041 def sense(self): 00042 now = datetime.now() 00043 elapsed = now - self.then 00044 self.then = now 00045 elapsed = float(elapsed.seconds) + elapsed.microseconds/1000000. 00046 d = self.create.d_distance / 1000. 00047 th = self.create.d_angle*pi/180 00048 dx = d / elapsed 00049 dth = th / elapsed 00050 00051 if (d != 0): 00052 x = cos(th)*d 00053 y = -sin(th)*d 00054 self.x = self.x + (cos(self.th)*x - sin(self.th)*y) 00055 self.y = self.y + (sin(self.th)*x + cos(self.th)*y) 00056 00057 if (th != 0): 00058 self.th = self.th + th 00059 00060 quaternion = Quaternion() 00061 quaternion.x = 0.0 00062 quaternion.y = 0.0 00063 quaternion.z = sin(self.th/2) 00064 quaternion.w = cos(self.th/2) 00065 00066 self.odomBroadcaster.sendTransform( 00067 (self.x, self.y, 0), 00068 (quaternion.x, quaternion.y, quaternion.z, quaternion.w), 00069 rospy.Time.now(), 00070 "base_link", 00071 "odom" 00072 ) 00073 00074 odom = Odometry() 00075 odom.header.stamp = rospy.Time.now() 00076 odom.header.frame_id = "odom" 00077 odom.pose.pose.position.x = self.x 00078 odom.pose.pose.position.y = self.y 00079 odom.pose.pose.position.z = 0 00080 odom.pose.pose.orientation = quaternion 00081 00082 odom.child_frame_id = "base_link" 00083 odom.twist.twist.linear.x = dx 00084 odom.twist.twist.linear.y = 0 00085 odom.twist.twist.angular.z = dth 00086 00087 self.odomPub.publish(odom) 00088 00089 packet = SensorPacket() 00090 for field in self.fields: 00091 packet.__setattr__(field,self.create.__getattr__(field)) 00092 self.packetPub.publish(packet) 00093 00094 charge_level = float(packet.batteryCharge) / float(packet.batteryCapacity) 00095 if (self.docking and packet.homeBase and charge_level > 0.95): 00096 self.docking = False 00097 self.create.reset() 00098 rospy.sleep(1) 00099 self.create.start() 00100 elif (not self.docking and charge_level < self.autodock): 00101 self.create.demo(1) 00102 self.docking = True 00103 00104 def brake(self,req): 00105 if (req.brake): 00106 self.create.brake() 00107 return BrakeResponse(True) 00108 00109 def circle(self,req): 00110 if (req.clear): 00111 self.create.clear() 00112 self.create.forwardTurn(req.speed,req.radius) 00113 return CircleResponse(True) 00114 00115 def demo(self,req): 00116 self.create.demo(req.demo) 00117 return DemoResponse(True) 00118 00119 def leds(self,req): 00120 self.create.leds(req.advance,req.play,req.color,req.intensity) 00121 return LedsResponse(True) 00122 00123 def tank(self,req): 00124 if (req.clear): 00125 self.create.clear() 00126 self.create.tank(req.left,req.right) 00127 return TankResponse(True) 00128 00129 def turn(self,req): 00130 if (req.clear): 00131 self.create.clear() 00132 self.create.turn(req.turn) 00133 return TurnResponse(True) 00134 00135 def dock(self,req): 00136 self.create.demo(1) 00137 self.docking = True 00138 return DockResponse(True) 00139 00140 def twist(self,req): 00141 x = req.linear.x*1000. 00142 th = req.angular.z 00143 if (x == 0): 00144 th = th*180/pi 00145 speed = (8*pi*th)/9 00146 self.create.left(int(speed)) 00147 elif (th == 0): 00148 x = int(x) 00149 self.create.tank(x,x) 00150 else: 00151 self.create.forwardTurn(int(x),int(x/th)) 00152 00153 if __name__ == '__main__': 00154 node = rospy.init_node('create') 00155 driver = CreateDriver() 00156 00157 rospy.Service('brake',Brake,driver.brake) 00158 rospy.Service('circle',Circle,driver.circle) 00159 rospy.Service('demo',Demo,driver.demo) 00160 rospy.Service('leds',Leds,driver.leds) 00161 rospy.Service('tank',Tank,driver.tank) 00162 rospy.Service('turn',Turn,driver.turn) 00163 rospy.Service('dock',Dock,driver.dock) 00164 00165 rospy.Subscriber("cmd_vel", Twist, driver.twist) 00166 00167 sleep(1) 00168 driver.start() 00169 sleep(1) 00170 00171 rospy.spin() 00172 driver.stop()