dynamic_reconfigure_server.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Software License Agreement (BSD License)
3 #
4 # Copyright (c) 2018 Svenzva Robotics LLC
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 Dynamic parameter server for control loop parameters for the Revel robotic arm
36 and its motors.
37 
38 Each motor can have its individual
39  Positional P, I, D, feedforward_velocity, feedforward_acceleration
40  velocity_profile (and speed)
41  acceleration_profile (and acceleration)
42 
43 where the velocity and acceleration profiles are determined by a comparison of values
44 between the two profiles. The values themselves set the target motor speed and acceleration
45 while the profile determines the motor speed and acceleration over time.
46 
47 See Dynamixel 2.0 Firmware Manual, sections Profile Velocity and Profile Acceleration for more details.
48 
49 
50 NOTE: Setting control parameters manually can cause the control loop to become unstable,
51 potentially harming the environment and the robot.
52 
53 To change control parameters, you must first check the 'enable control parameters' checkbox in the
54 rqt_reconfigure window. You then proceed AT YOUR OWN RISK.
55 
56 Author: Maxwell Svetlik
57 """
58 
59 
60 import rospy
61 
62 from dynamic_reconfigure.server import Server
63 from std_srvs.srv import Empty
64 from svenzva_drivers.cfg import RevelFirmwareDynamicConfig
65 
66 
68 
69  def __init__(self, controller_namespace, mx_io):
72  self.mx_io = mx_io
73  self.controller_namespace = controller_namespace
74  self.gr = [4,7,7,3,4,1,1]
75 
77  config = self.last_configuration
78  self.set_acceleration_profile(config.joint_acc_limit)
79  self.set_velocity_profile(config.joint_vel_limit)
80  self.set_position_PID(1, config.joint_1_P, config.joint_1_I, config.joint_1_D, config.joint_1_Feedforward1_velocity, config.joint_1_Feedforward2_acceleration, config.joint_1_velocity_P, config.joint_1_velocity_I)
81  self.set_position_PID(2, config.joint_2_P, config.joint_2_I, config.joint_2_D, config.joint_2_Feedforward1_velocity, config.joint_2_Feedforward2_acceleration, config.joint_2_velocity_P, config.joint_2_velocity_I)
82  self.set_position_PID(3, config.joint_3_P, config.joint_3_I, config.joint_3_D, config.joint_3_Feedforward1_velocity, config.joint_3_Feedforward2_acceleration, config.joint_3_velocity_P, config.joint_3_velocity_I)
83  self.set_position_PID(4, config.joint_4_P, config.joint_4_I, config.joint_4_D, config.joint_4_Feedforward1_velocity, config.joint_4_Feedforward2_acceleration, config.joint_4_velocity_P, config.joint_4_velocity_I)
84  self.set_position_PID(5, config.joint_5_P, config.joint_5_I, config.joint_5_D, config.joint_5_Feedforward1_velocity, config.joint_5_Feedforward2_acceleration, config.joint_5_velocity_P, config.joint_5_velocity_I)
85  self.set_position_PID(6, config.joint_6_P, config.joint_6_I, config.joint_6_D, config.joint_6_Feedforward1_velocity, config.joint_6_Feedforward2_acceleration, config.joint_6_velocity_P, config.joint_6_velocity_I)
86  self.set_position_PID(7, config.joint_7_P, config.joint_7_I, config.joint_7_D, config.joint_7_Feedforward1_velocity, config.joint_7_Feedforward2_acceleration, config.joint_7_velocity_P, config.joint_7_velocity_I)
87  return self.last_configuration
88 
89  def set_current_config(self, data):
91  return []
92 
93  def callback(self, config, level):
94  #first run
95  if self.is_first_configuration:
96  self.last_configuration = config.copy()
97  self.is_first_configuration = False
98  # load initial values
99  return self.set_last_configuration()
100 
101  #if user hasn't enabled parameter control, do not process parameter changes
102  if not config.enable_parameter_control:
103  return self.last_configuration
104 
105  #process parameter changes
106  if level & 1: #acceleration profile
107  if config.joint_acc_limit != self.last_configuration.joint_acc_limit:
108  self.set_acceleration_profile(config.joint_acc_limit)
109 
110  if level & 1<<1: #velocity profile
111  if config.joint_vel_limit != self.last_configuration.joint_vel_limit:
112  self.set_velocity_profile(config.joint_vel_limit)
113 
114  if level & 1<<2: # Joint 1 PID
115  self.set_position_PID(1, config.joint_1_P, config.joint_1_I, config.joint_1_D, config.joint_1_Feedforward1_velocity, config.joint_1_Feedforward2_acceleration, config.joint_1_velocity_P, config.joint_1_velocity_I)
116  if level & 1<<3: #Joint 2 PID
117  self.set_position_PID(2, config.joint_2_P, config.joint_2_I, config.joint_2_D, config.joint_2_Feedforward1_velocity, config.joint_2_Feedforward2_acceleration, config.joint_2_velocity_P, config.joint_2_velocity_I)
118  if level & 1<<4: #Joint 3 PID
119  self.set_position_PID(3, config.joint_3_P, config.joint_3_I, config.joint_3_D, config.joint_3_Feedforward1_velocity, config.joint_3_Feedforward2_acceleration, config.joint_3_velocity_P, config.joint_3_velocity_I)
120  if level & 1<<5: #Joint 4 PID
121  self.set_position_PID(4, config.joint_4_P, config.joint_4_I, config.joint_4_D, config.joint_4_Feedforward1_velocity, config.joint_4_Feedforward2_acceleration, config.joint_4_velocity_P, config.joint_4_velocity_I)
122  if level & 1<<6: #Joint 5 PID
123  self.set_position_PID(5, config.joint_5_P, config.joint_5_I, config.joint_5_D, config.joint_5_Feedforward1_velocity, config.joint_5_Feedforward2_acceleration, config.joint_5_velocity_P, config.joint_5_velocity_I)
124  if level & 1<<7: #Joint 6 PID
125  self.set_position_PID(6, config.joint_6_P, config.joint_6_I, config.joint_6_D, config.joint_6_Feedforward1_velocity, config.joint_6_Feedforward2_acceleration, config.joint_6_velocity_P, config.joint_6_velocity_I)
126  if level & 1<<8: #Joint 7 PID
127  self.set_position_PID(7, config.joint_7_P, config.joint_7_I, config.joint_7_D, config.joint_7_Feedforward1_velocity, config.joint_7_Feedforward2_acceleration, config.joint_7_velocity_P, config.joint_7_velocity_I)
128 
129  self.last_configuration = config.copy()
130  return config
131 
132  def set_position_PID(self, motor_id, p_gain_val, i_gain_val, d_gain_val, ff1_gain, ff2_gain, vel_p, vel_i):
133  self.mx_io.set_position_p_gain(motor_id, p_gain_val)
134  self.mx_io.set_position_i_gain(motor_id, i_gain_val)
135  self.mx_io.set_position_d_gain(motor_id, d_gain_val)
136  self.mx_io.set_position_feedfwd1_gain(motor_id, ff1_gain)
137  self.mx_io.set_position_feedfwd2_gain(motor_id, ff2_gain)
138  self.mx_io.set_velocity_p_gain(motor_id, vel_p)
139  self.mx_io.set_velocity_i_gain(motor_id, vel_i)
140 
141  # scales all accelerations uniformly accounting for gear ratios
142  def set_acceleration_profile(self,gain):
143  self.mx_io.set_acceleration_profile(1, gain*self.gr[0])
144  self.mx_io.set_acceleration_profile(2, gain*self.gr[1])
145  self.mx_io.set_acceleration_profile(3, gain*self.gr[2])
146  self.mx_io.set_acceleration_profile(4, gain*self.gr[3])
147  self.mx_io.set_acceleration_profile(5, gain*self.gr[4])
148  self.mx_io.set_acceleration_profile(6, gain*self.gr[5])
149  self.mx_io.set_acceleration_profile(7, gain*self.gr[6])
150 
151  # scales all velocity unfiformly accounting for gear ratios
152  def set_velocity_profile(self, gain):
153  self.mx_io.set_velocity_profile(1, gain*self.gr[0])
154  self.mx_io.set_velocity_profile(2, gain*self.gr[1])
155  self.mx_io.set_velocity_profile(3, gain*self.gr[2])
156  self.mx_io.set_velocity_profile(4, gain*self.gr[3])
157  self.mx_io.set_velocity_profile(5, gain*self.gr[4])
158  self.mx_io.set_velocity_profile(6, gain*self.gr[5])
159  self.mx_io.set_velocity_profile(7, gain*self.gr[6])
160 
161  def start(self):
162  srv = Server(RevelFirmwareDynamicConfig, self.callback)
163  last_config_srv = rospy.Service('revel/reload_firmware_parameters', Empty, self.set_current_config)
164  rospy.spin()
165 
166 if __name__ == "__main__":
167  rospy.init_node("svenzva_drivers_reconfigure", anonymous = False)
169  rdps.start()
def set_position_PID(self, motor_id, p_gain_val, i_gain_val, d_gain_val, ff1_gain, ff2_gain, vel_p, vel_i)


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