RiCDiffCloseLoop.py
Go to the documentation of this file.
00001 import re
00002 from threading import Thread
00003 from nav_msgs.msg import Odometry
00004 import rospy
00005 import rostopic
00006 from BAL.Header.Requests.PublishRequest import PublishRequest
00007 from BAL.Header.Requests.closeDiffRequest import CloseDiffRequest
00008 from BAL.Header.Requests.closeDiffSetOdomRequest import CloseDiffSetOdomRequest
00009 from BAL.Header.Response.ParamBuildResponse import DiffDriverCL
00010 
00011 __author__ = 'tom1231'
00012 from BAL.Interfaces.Device import Device
00013 from rospy import Subscriber, Service, Publisher
00014 from ric_board.srv._set_odom import set_odom, set_odomResponse
00015 from tf import TransformBroadcaster
00016 from tf.transformations import euler_from_quaternion
00017 from geometry_msgs.msg import Twist, TransformStamped, Quaternion
00018 import math
00019 
00020 
00021 class RiCDiffCloseLoop(Device):
00022     def __init__(self, param, output):
00023         Device.__init__(self, param.getCloseDiffName(), output)
00024         self._baseLink = param.getCloseDiffBaseLink()
00025         self._odom = param.getCloseDiffOdom()
00026         self._maxAng = param.getCloseDiffMaxAng()
00027         self._maxLin = param.getCloseDiffMaxLin()
00028         self._pub = Publisher("%s/odometry" % self._name, Odometry, queue_size=param.getCloseDiffPubHz())
00029         self._broadCase = TransformBroadcaster()
00030         Subscriber('%s/command' % self._name, Twist, self.diffServiceCallback, queue_size=1)
00031         Service('%s/setOdometry' % self._name, set_odom, self.setOdom)
00032         self._haveRightToPublish = False
00033         self._prevOdom = None
00034         self._firstTimePub = True
00035 
00036     def getType(self):
00037         return DiffDriverCL
00038 
00039     def diffServiceCallback(self, msg):
00040         Thread(target=self.sendMsg, args=(msg,)).start()
00041 
00042     def sendMsg(self, msg):
00043         if msg.angular.z > self._maxAng:
00044             msg.angular.z = self._maxAng
00045         elif msg.angular.z < -self._maxAng:
00046             msg.angular.z = -self._maxAng
00047 
00048         if msg.linear.x > self._maxLin:
00049             msg.linear.x = self._maxLin
00050         elif msg.linear.x < -self._maxLin:
00051             msg.linear.x = -self._maxLin
00052         # print msg.angular.z, msg.linear.x
00053         self._output.write(CloseDiffRequest(msg.angular.z, msg.linear.x).dataTosend())
00054 
00055     def setOdom(self, req):
00056         self._output.write(CloseDiffSetOdomRequest(req.x, req.y, req.theta).dataTosend())
00057         return set_odomResponse(True)
00058 
00059     def publish(self, data):
00060         q = Quaternion()
00061         q.x = 0
00062         q.y = 0
00063         q.z = data[6]
00064         q.w = data[7]
00065         odomMsg = Odometry()
00066         odomMsg.header.frame_id = self._odom
00067         odomMsg.header.stamp = rospy.get_rostime()
00068         odomMsg.child_frame_id = self._baseLink
00069         odomMsg.pose.pose.position.x = data[0]
00070         odomMsg.pose.pose.position.y = data[1]
00071         odomMsg.pose.pose.position.z = 0
00072         odomMsg.pose.pose.orientation = q
00073         if self._firstTimePub:
00074             self._prevOdom = odomMsg
00075             self._firstTimePub = False
00076             return
00077 
00078         velocity = Twist()
00079 
00080         deltaTime = odomMsg.header.stamp.to_sec() - self._prevOdom.header.stamp.to_sec()
00081         yaw, pitch, roll = euler_from_quaternion(
00082             [odomMsg.pose.pose.orientation.w, odomMsg.pose.pose.orientation.x, odomMsg.pose.pose.orientation.y,
00083              odomMsg.pose.pose.orientation.z])
00084         prevYaw, prevPitch, prevRollprevYaw = euler_from_quaternion(
00085             [self._prevOdom.pose.pose.orientation.w, self._prevOdom.pose.pose.orientation.x,
00086              self._prevOdom.pose.pose.orientation.y, self._prevOdom.pose.pose.orientation.z])
00087         if deltaTime > 0:
00088             velocity.linear.x = (data[8] / deltaTime)
00089 
00090         deltaYaw = yaw - prevYaw
00091 
00092         # rospy.loginfo("yaw: %f\t\tpevYaw: %f\t\tdeltaYaw: %f" % (yaw,prevYaw,deltaYaw))
00093 
00094         if deltaYaw > math.pi: deltaYaw -= 2 * math.pi
00095         elif deltaYaw < -math.pi: deltaYaw += 2 * math.pi
00096 
00097         if deltaTime > 0:
00098             velocity.angular.z = -(deltaYaw / deltaTime)
00099 
00100         # rospy.loginfo("deltaYaw after check: %f\t\t angular: %f" % (deltaYaw, velocity.angular.z))
00101 
00102         odomMsg.twist.twist = velocity
00103 
00104         self._prevOdom = odomMsg
00105 
00106         traMsg = TransformStamped()
00107         traMsg.header.frame_id = self._odom
00108         traMsg.header.stamp = rospy.get_rostime()
00109         traMsg.child_frame_id = self._baseLink
00110         traMsg.transform.translation.x = data[0]
00111         traMsg.transform.translation.y = data[1]
00112         traMsg.transform.translation.z = 0
00113         traMsg.transform.rotation = q
00114 
00115         self._pub.publish(odomMsg)
00116         self._broadCase.sendTransformMessage(traMsg)
00117 
00118     def checkForSubscribers(self):
00119         try:
00120             subCheck = re.search('Subscribers:.*', rostopic.get_info_text(self._pub.name)).group(0).split(': ')[1]
00121             subTfCheck = re.search('Subscribers:.*', rostopic.get_info_text('/tf')).group(0).split(': ')[1]
00122 
00123             if not self._haveRightToPublish and (subCheck == '' or subTfCheck == ''):
00124                 self._output.write(PublishRequest(DiffDriverCL, 0, True).dataTosend())
00125                 self._haveRightToPublish = True
00126 
00127             elif self._haveRightToPublish and (subCheck == 'None' and subTfCheck == 'None'):
00128                 self._output.write(PublishRequest(DiffDriverCL, 0, False).dataTosend())
00129                 self._haveRightToPublish = False
00130                 self._firstTimePub = True
00131         except:
00132             pass


ric_board
Author(s): RoboTiCan
autogenerated on Fri Oct 27 2017 03:02:31