revel_arm_services.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Software License Agreement (BSD License)
3 #
4 # Copyright (c) 2017 Svenzva Robotics
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 # * Neither the name of Svenzva Robotics LLC nor the names of its
18 # contributors may be used to endorse or promote products derived
19 # from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 
34 """
35 Svenzva's Revel general utility service interface
36 
37 Includes exposing the following services:
38  + Arm torque enabled / disabled
39  + Finger position reset (finger-removal service)
40  + Finger hotswap (finger-insert service)
41 Author: Maxwell Svetlik
42 """
43 from __future__ import division
44 from threading import Thread
45 
46 import rospy
47 import actionlib
48 import rospkg
49 import yaml
50 
51 from std_srvs.srv import Empty
52 from std_msgs.msg import Float64, Int32
53 from svenzva_msgs.msg import MotorState, MotorStateList, GripperFeedback, GripperResult, GripperAction
54 
55 from svenzva_msgs.srv import SetTorqueEnable, HomeArm, SetControlMode
56 
57 
59 
60 
61  def __init__(self, controller_namespace, mx_io, num_motors):
62  self.mx_io = mx_io
63  self.num_motors = num_motors
64  self.gripper_id = 7
65  self.torque_srv = rospy.Service('/revel/SetControlMode', SetControlMode, self.control_mode_cb)
66  self.torque_srv = rospy.Service('/revel/SetTorqueEnable', SetTorqueEnable, self.torque_enable_cb)
67  self.home_srv =rospy.Service('home_arm_service', HomeArm, self.home_arm)
68  self.remove_fingers = rospy.Service('/revel/gripper/remove_fingers', Empty, self.remove_fingers_cb)
69  self.insert_fingers = rospy.Service('/revel/gripper/insert_fingers', Empty, self.insert_fingers_cb)
70  self.motor_state = MotorState()
71  rospy.Subscriber("revel/motor_states", MotorStateList, self.motor_state_cb, queue_size=1)
72 
73  self.reset_pos = -3.4
74 
75  def motor_state_cb(self, data):
76  if self.num_motors >= self.gripper_id:
77  self.motor_state = data.motor_states[self.gripper_id - 1]
78 
79 
80  """
81  Service call back that pushes fingers out of gripper and resets motor position for correct finger
82  position tracking.
83  """
84  def remove_fingers_cb(self, data):
85  force = 25
86  if self.num_motors >= self.gripper_id:
87  cur_pos = self.motor_state.position
88 
89  #switch to position mode for simplicity
90  self.mx_io.set_torque_enabled(7, 0)
91  self.mx_io.set_torque_enabled(7, 1)
92 
93  self.mx_io.set_position(7, int(round(self.reset_pos * 4096.0 / 6.2831853)))
94  rospy.sleep(5.0)
95 
96  #switch back to torque mode
97  self.mx_io.set_torque_enabled(7, 0)
98  self.mx_io.set_operation_mode(7, 0)
99  self.mx_io.set_torque_enabled(7, 1)
100 
101  return
102 
103  """
104  Service used in conjunction with `remove_fingers` service. This service should be called after the
105  fingers have been pushed into the gripper by the user.
106  """
107  def insert_fingers_cb(self, data):
108  if self.num_motors >= self.gripper_id:
109  self.mx_io.set_torque_enabled(7, 0)
110  self.mx_io.set_operation_mode(7, 4)
111  self.mx_io.set_torque_enabled(7, 1)
112 
113  self.mx_io.set_position(7, int(round(0 * 4096.0 / 6.2831853)))
114  rospy.sleep(5.0)
115 
116 
117  self.mx_io.set_torque_enabled(7, 0)
118  self.mx_io.set_operation_mode(7, 0)
119  self.mx_io.set_torque_enabled(7, 1)
120 
121  return
122 
123  def control_mode_cb(self, data):
124  tup_list_op = tuple()
125  if data.control_mode == data.POSITION:
126  tup_list_op = tuple(((1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,0)))
127  elif data.control_mode == data.VELOCITY:
128  tup_list_op = tuple(((1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,0)))
129  elif data.control_mode == data.TORQUE:
130  tup_list_op = tuple(((1,0),(2,0),(3,0),(4,0),(5,0),(6,0),(7,0)))
131  else:
132  tup_list_op = tuple(((1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,0)))
133  tup_list_dis = tuple(((1,0),(2,0),(3,0),(4,0),(5,0),(6,0),(7,0)))
134  tup_list_en = tuple(((1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1)))
135  self.mx_io.sync_set_torque_enabled(tup_list_dis)
136  self.mx_io.sync_set_operation_mode(tup_list_op)
137  self.mx_io.sync_set_torque_enabled(tup_list_en)
138  self.reset_motor_parmeters()
139  return True
140 
141  def torque_enable_cb(self, data):
142  if len(data.motor_list) != self.num_motors:
143  rospy.logerr("SetTorqueEnable: input motor_list is not the right length. Aborting.")
144  #data.success = False
145  return
146  for i, val in enumerate(data.motor_list):
147  if val > 1 or val < 0:
148  rospy.logwarn("Torque value for motor %d was not binary. Interpreting as ENABLE.", i)
149  val = 1
150  self.mx_io.set_torque_enabled(i+1, val)
151  rospy.sleep(0.01)
152  self.reset_motor_parmeters()
153  def torque_goal_cb(self, data):
154  if len(data.data) != self.num_motors:
155  rospy.logerr("SetTorqueEnable: input motor_list is not the right length. Aborting.")
156  return
157  cmds = []
158  for i, val in enumerate(data.data):
159  cmds.append( (i+1, val))
160  self.mx_io.set_multi_current(tuple(cmds))
161  rospy.sleep(0.01)
162 
163  def start(self):
164  rospy.loginfo("Starting RevelArmServices...")
165  rospy.spin()
166 
167  """
168  Calls a service that restores the control parameters for each motor, which get reset to defaults when torque is
169  disabled, which happes when a user changes modes or dis/enables torque
170  """
172  try:
173  reset_motor_param = rospy.ServiceProxy('/revel/reload_firmware_parameters', Empty)
174  return reset_motor_param()
175  except rospy.ServiceException, e:
176  rospy.loginfo("Unable to reset motor parmeters after context change... call failed: %s"%e)
177 
178 
179  def home_arm(self, data):
180  # load the yaml file that specifies the home position
181  rospack = rospkg.RosPack()
182  path = rospack.get_path('svenzva_drivers')
183  f = open(path+"/config/home_position.yaml")
184  qmap = yaml.safe_load(f)
185  f.close()
186 
187  #2 - execute action on yaml file
188  req = SvenzvaJointGoal()
189  if len(qmap['home']) < 6:
190  rospy.logerr("Could not home arm. Home position configuration file ill-formed or missing. Aborting.")
191  return
192  req.positions = qmap['home']
193 
194  fkine = actionlib.SimpleActionClient('/svenzva_joint_action', SvenzvaJointAction)
195 
196  fkine.wait_for_server()
197  rospy.loginfo("Found Trajectory action server")
198  rospy.loginfo("Homing arm...")
199  fkine.send_goal_and_wait(req)
200 
def __init__(self, controller_namespace, mx_io, num_motors)


svenzva_drivers
Author(s): Max Svetlik
autogenerated on Wed Oct 28 2020 03:31:27