joint_state_publisher.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 #####
00004 #####
00005 # This script is copied from https://github.com/arebgun/dynamixel_motor/pull/27
00006 #####
00007 #####
00008 #
00009 # Software License Agreement (BSD License)
00010 #
00011 # Copyright (c) 2015, Kei Okada.
00012 # All rights reserved.
00013 #
00014 # Redistribution and use in source and binary forms, with or without
00015 # modification, are permitted provided that the following conditions
00016 # are met:
00017 #
00018 #  * Redistributions of source code must retain the above copyright
00019 #    notice, this list of conditions and the following disclaimer.
00020 #  * Redistributions in binary form must reproduce the above
00021 #    copyright notice, this list of conditions and the following
00022 #    disclaimer in the documentation and/or other materials provided
00023 #    with the distribution.
00024 #  * Neither the name of Kei Okada nor the names of its
00025 #    contributors may be used to endorse or promote products derived
00026 #    from this software without specific prior written permission.
00027 #
00028 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00031 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00032 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00033 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00034 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00035 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00036 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00038 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00039 # POSSIBILITY OF SUCH DAMAGE.
00040 
00041 from threading import Thread
00042 
00043 import rospy
00044 
00045 from sensor_msgs.msg import JointState
00046 
00047 class JointStatePublisher():
00048     def __init__(self, controller_namespace, controllers):
00049         self.update_rate = 1000
00050         self.state_update_rate = 50
00051         self.trajectory = []
00052         
00053         self.controller_namespace = controller_namespace
00054         self.joint_names = [c.joint_name for c in controllers]
00055         self.pre_position = []
00056         self.abs_position = []
00057 
00058         self.joint_to_controller = {}
00059         for c in controllers:
00060              self.joint_to_controller[c.joint_name] = c
00061             
00062         self.port_to_joints = {}
00063         for c in controllers:
00064             if c.port_namespace not in self.port_to_joints: self.port_to_joints[c.port_namespace] = []
00065             self.port_to_joints[c.port_namespace].append(c.joint_name)
00066             
00067         self.port_to_io = {}
00068         for c in controllers:
00069             if c.port_namespace in self.port_to_io: continue
00070             self.port_to_io[c.port_namespace] = c.dxl_io
00071 
00072     def initialize(self):
00073         self.msg = JointState()
00074         return True
00075 
00076 
00077     def start(self):
00078         self.running = True
00079         self.state_pub = rospy.Publisher('joint_states', JointState , queue_size=100)
00080 
00081         Thread(target=self.update_state).start()
00082 
00083 
00084     def stop(self):
00085         self.running = False
00086 
00087     def update_state(self):
00088         rate = rospy.Rate(self.state_update_rate)
00089         while self.running and not rospy.is_shutdown():
00090             self.msg.header.stamp = rospy.Time.now()
00091             self.msg.name = []
00092             self.msg.position = []
00093             self.msg.velocity = []
00094             self.msg.effort = []
00095             
00096             i = 0
00097             for port, joints in self.port_to_joints.items():
00098                 vals = []
00099                 rospy.logdebug("joints : "+" ".join(joints))
00100                 for joint in joints:
00101                     j = self.joint_names.index(joint)
00102                     
00103                     motor_id = self.joint_to_controller[joint].motor_id
00104                     co = self.joint_to_controller[joint]
00105                     io = self.port_to_io[port]
00106                     rospy.logdebug("port={} id={}, {}".format(port, motor_id, joint))
00107 
00108                     self.msg.name.append(joint)
00109                     po = ve = ef = 0
00110                     try:
00111                         ret = io.get_feedback(motor_id)
00112                         if len(self.abs_position) == 0:
00113                             po = self.raw_to_rad_pos(ret['position'],co)
00114                         else:
00115                             if (ret['position'] - self.pre_position[i]) < -3072:
00116                                 self.abs_position[i] = self.abs_position[i] + (ret['position'] - self.pre_position[i] + 4096)
00117                             elif  (ret['position'] - self.pre_position[i]) > 3072:
00118                                 self.abs_position[i] = self.abs_position[i] + (ret['position'] - self.pre_position[i] - 4096)
00119                             else:
00120                                 self.abs_position[i] = self.abs_position[i] + (ret['position'] - self.pre_position[i])
00121                             self.pre_position[i] = ret['position']
00122                             po = self.raw_to_rad_pos(self.abs_position[i],co)
00123                         ve = self.raw_to_rad_spd(ret['speed'],co)
00124                         ef = self.raw_to_rad_spd(ret['load'],co)
00125                         #po = self.raw_to_rad_pos(io.get_position(motor_id),co)
00126                         #ve = self.raw_to_rad_spd(io.get_speed(motor_id),co)
00127                         #ef = io.get_current(motor_id)
00128                     except Exception as e:
00129                         rospy.logerr(e)
00130                     self.msg.position.append(po)
00131                     self.msg.velocity.append(ve)
00132                     self.msg.effort.append(ef)
00133                     i += 1
00134 
00135             # initialize pre_position and abs_position
00136             if len(self.pre_position) != len(self.msg.position):
00137                 self.pre_position = [0]*len(self.msg.position)
00138                 self.abs_position = [0]*len(self.msg.position)
00139                 i = 0
00140                 for port, joints in self.port_to_joints.items():
00141                     for joint in joints:
00142                         j = self.joint_names.index(joint)
00143                         motor_id = self.joint_to_controller[joint].motor_id
00144                         io = self.port_to_io[port]
00145                         ret = io.get_feedback(motor_id)
00146                         self.pre_position[i] = ret['position']
00147                         self.abs_position[i] = ret['position']
00148                         i+= 1
00149 
00150             self.state_pub.publish(self.msg)
00151             rate.sleep()
00152 
00153     def raw_to_rad_pos(self, raw, c):
00154         return (c.initial_position_raw - raw if c.flipped else raw - c.initial_position_raw) * c.RADIANS_PER_ENCODER_TICK
00155     def raw_to_rad_spd(self, raw, c):
00156         return (- raw if c.flipped else raw ) * c.RADIANS_PER_ENCODER_TICK


spur_controller
Author(s): Tokyo Opensource Robotics Programmer 534o <534o@opensource-robotics.tokyo.jp>, Isaac I. Y. Saito
autogenerated on Sat Jun 8 2019 19:44:12