Skip to content

Commit 7d10df4

Browse files
committed
1 parent 9b4e3b4 commit 7d10df4

4 files changed

Lines changed: 156 additions & 2 deletions

File tree

dynamixel_controllers/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 2.8.3)
22
project(dynamixel_controllers)
33

4-
find_package(catkin REQUIRED COMPONENTS message_generation)
4+
find_package(catkin REQUIRED COMPONENTS actionlib message_generation)
55

66
add_service_files(
77
FILES
@@ -16,9 +16,14 @@ add_service_files(
1616
TorqueEnable.srv
1717
)
1818

19+
add_action_files(
20+
DIRECTORY action
21+
FILES CalibJoint.action
22+
)
23+
1924
catkin_python_setup()
2025

21-
generate_messages()
26+
generate_messages(DEPENDENCIES std_msgs actionlib_msgs)
2227

2328
catkin_package(
2429
CATKIN_DEPENDS
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

dynamixel_controllers/package.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222

2323
<buildtool_depend>catkin</buildtool_depend>
2424

25+
<build_depend>actionlib</build_depend>
26+
<build_depend>actionlib_msgs</build_depend>
2527
<build_depend>message_generation</build_depend>
28+
<build_depend>std_msgs</build_depend>
2629

2730
<run_depend>rospy</run_depend>
2831
<run_depend>actionlib</run_depend>
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import rospy
2+
import actionlib
3+
from dynamixel_controllers.joint_position_controller import (
4+
JointPositionController,
5+
)
6+
from dynamixel_msgs.msg import MotorStateList
7+
from std_srvs.srv import Trigger
8+
from std_srvs.srv import TriggerResponse
9+
from dynamixel_controllers.msg import (
10+
CalibJointAction,
11+
CalibJointResult,
12+
)
13+
14+
15+
class CalibRequiredJointController(JointPositionController):
16+
def __init__(self, dxl_io, controller_namespace, port_namespace):
17+
JointPositionController.__init__(self, dxl_io, controller_namespace,
18+
port_namespace)
19+
20+
self.calib_speed = rospy.get_param(
21+
self.controller_namespace + '/calib_speed',
22+
0.1)
23+
self.calib_torque_limit = rospy.get_param(
24+
self.controller_namespace + '/calib_torque_limit',
25+
0.3)
26+
self.detect_limit_load = rospy.get_param(
27+
self.controller_namespace + '/detect_limit_load',
28+
0.15)
29+
self.is_multiturn = rospy.get_param(
30+
self.controller_namespace + '/is_multiturn',
31+
False)
32+
33+
self.calib_server = actionlib.SimpleActionServer(
34+
self.controller_namespace + '/calib',
35+
CalibJointAction,
36+
execute_cb=self.on_calib_action,
37+
auto_start=False)
38+
39+
def initialize(self):
40+
if not JointPositionController.initialize(self):
41+
return False
42+
43+
self.__calib()
44+
self.calib_server.start()
45+
46+
return (not rospy.is_shutdown())
47+
48+
def on_calib_action(self, goal):
49+
self.__calib()
50+
self.calib_server.set_succeeded(CalibJointResult())
51+
52+
def __calib(self):
53+
# Initialize joint position
54+
55+
self.motor_states_for_init = {}
56+
motor_states_sub_for_init = rospy.Subscriber('motor_states/%s' % self.port_namespace, MotorStateList, self.get_motor_states_for_init)
57+
self.set_speed(0.0)
58+
# Backup current angle limits
59+
prev_limits = self.__get_angle_limits()
60+
# Change to wheel mode
61+
self.__set_angle_limits(0, 0)
62+
self.set_torque_limit(self.calib_torque_limit)
63+
self.__set_speed_wheel(0.0)
64+
# release torque by disabling it
65+
self.set_torque_enable(False)
66+
rospy.sleep(0.2)
67+
self.set_torque_enable(True) # re-enable it
68+
rospy.sleep(0.2)
69+
if self.flipped:
70+
self.__set_speed_wheel(self.calib_speed)
71+
else:
72+
self.__set_speed_wheel(-self.calib_speed)
73+
rate = rospy.Rate(50)
74+
while not rospy.is_shutdown():
75+
try:
76+
init_pos = self.motor_states_for_init['position']
77+
if abs(self.motor_states_for_init['load']) > self.detect_limit_load:
78+
break
79+
except KeyError:
80+
pass
81+
rate.sleep()
82+
self.__set_speed_wheel(0.0)
83+
if self.is_multiturn:
84+
# Change to multiturn mode
85+
self.__set_angle_limits(4095, 4095)
86+
else:
87+
# Change to previous mode
88+
self.__set_angle_limits(prev_limits['min'], prev_limits['max'])
89+
self.set_torque_enable(False)
90+
self.set_speed(self.joint_speed)
91+
rospy.sleep(0.5)
92+
if self.torque_limit is not None:
93+
self.set_torque_limit(self.torque_limit)
94+
motor_states_sub_for_init.unregister()
95+
96+
# Remember initial joint position
97+
diff = init_pos - self.initial_position_raw
98+
self.initial_position_raw += diff
99+
rospy.set_param(self.controller_namespace + '/motor/init',
100+
self.initial_position_raw)
101+
self.min_angle_raw += diff
102+
rospy.set_param(self.controller_namespace + '/motor/min',
103+
self.min_angle_raw)
104+
self.max_angle_raw += diff
105+
rospy.set_param(self.controller_namespace + '/motor/max',
106+
self.max_angle_raw)
107+
if self.flipped:
108+
self.min_angle = ((self.initial_position_raw -
109+
self.min_angle_raw) *
110+
self.RADIANS_PER_ENCODER_TICK)
111+
self.max_angle = ((self.initial_position_raw -
112+
self.max_angle_raw) *
113+
self.RADIANS_PER_ENCODER_TICK)
114+
else:
115+
self.min_angle = ((self.min_angle_raw -
116+
self.initial_position_raw) *
117+
self.RADIANS_PER_ENCODER_TICK)
118+
self.max_angle = ((self.max_angle_raw -
119+
self.initial_position_raw) *
120+
self.RADIANS_PER_ENCODER_TICK)
121+
122+
def __set_angle_limits(self, min_angle, max_angle):
123+
self.dxl_io.set_angle_limits(self.motor_id, min_angle, max_angle)
124+
125+
def __get_angle_limits(self):
126+
return self.dxl_io.get_angle_limits(self.motor_id)
127+
128+
def get_motor_states_for_init(self, state_list):
129+
state = filter(lambda state: state.id == self.motor_id, state_list.motor_states)
130+
if state:
131+
state = state[0]
132+
self.motor_states_for_init['position'] = state.position
133+
self.motor_states_for_init['load'] = state.load
134+
135+
def __spd_rad_to_raw_wheel(self, spd_rad):
136+
if spd_rad < -self.joint_max_speed:
137+
spd_rad = -self.joint_max_speed
138+
elif spd_rad > self.joint_max_speed:
139+
spd_rad = self.joint_max_speed
140+
return int(round(spd_rad / self.VELOCITY_PER_TICK))
141+
142+
def __set_speed_wheel(self, speed):
143+
mcv = (self.motor_id, self.__spd_rad_to_raw_wheel(speed))
144+
self.dxl_io.set_multi_speed([mcv])

0 commit comments

Comments
 (0)