rov_ua_pid_controller.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (c) 2016-2019 The UUV Simulator Authors.
3 # All rights reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 import numpy as np
17 import rospy
18 from uuv_control_msgs.srv import *
19 from uuv_control_interfaces.dp_controller_base import DPControllerBase
20 
21 
23  """
24  This is an abstract class for PID-based controllers. The base class method
25  update_controller must be overridden in other for a controller to work.
26  """
27 
28  def __init__(self, *args):
29  # Start the super class
30  DPControllerBase.__init__(self, *args)
31  self._logger.info('Initializing: Underactuated PID controller')
32  # Proportional gains
33  self._Kp = np.zeros(shape=(4, 4))
34  # Derivative gains
35  self._Kd = np.zeros(shape=(4, 4))
36  # Integral gains
37  self._Ki = np.zeros(shape=(4, 4))
38  # Integrator component
39  self._int = np.zeros(4)
40  # Error for the vehicle pose
41  self._error_pose = np.zeros(4)
42 
43  if rospy.has_param('~Kp'):
44  Kp_diag = rospy.get_param('~Kp')
45  if len(Kp_diag) == 4:
46  self._Kp = np.diag(Kp_diag)
47  else:
48  raise rospy.ROSException('Kp matrix error: 4 coefficients '
49  'needed')
50 
51  self._logger.info('Kp=' + str([self._Kp[i, i] for i in range(4)]))
52 
53  if rospy.has_param('~Kd'):
54  Kd_diag = rospy.get_param('~Kd')
55  if len(Kd_diag) == 4:
56  self._Kd = np.diag(Kd_diag)
57  else:
58  raise rospy.ROSException('Kd matrix error: 4 coefficients '
59  'needed')
60 
61  self._logger.info('Kd=' + str([self._Kd[i, i] for i in range(4)]))
62 
63  if rospy.has_param('~Ki'):
64  Ki_diag = rospy.get_param('~Ki')
65  if len(Ki_diag) == 4:
66  self._Ki = np.diag(Ki_diag)
67  else:
68  raise rospy.ROSException('Ki matrix error: 4 coefficients '
69  'needed')
70 
71  self._logger.info('Ki=' + str([self._Ki[i, i] for i in range(4)]))
72 
73  self._services['set_pid_params'] = rospy.Service(
74  'set_pid_params',
75  SetPIDParams,
77  self._services['get_pid_params'] = rospy.Service(
78  'get_pid_params',
79  GetPIDParams,
81 
82  self._is_init = True
83  self._logger.info('Underactuated PID controller ready!')
84 
85  def _reset_controller(self):
86  super(DPPIDControllerBase, self)._reset_controller()
87  self._error_pose = np.zeros(4)
88  self._int = np.zeros(4)
89 
90  def set_pid_params_callback(self, request):
91  kp = request.Kp
92  kd = request.Kd
93  ki = request.Ki
94  if len(kp) != 4 or len(kd) != 4 or len(ki) != 4:
95  return SetPIDParamsResponse(False)
96  self._Kp = np.diag(kp)
97  self._Ki = np.diag(ki)
98  self._Kd = np.diag(kd)
99  return SetPIDParamsResponse(True)
100 
101  def get_pid_params_callback(self, request):
102  return GetPIDParamsResponse(
103  [self._Kp[i, i] for i in range(4)],
104  [self._Kd[i, i] for i in range(4)],
105  [self._Ki[i, i] for i in range(4)])
106 
107  def update_controller(self):
108  if not self.odom_is_init:
109  return False
110  if not self._is_init:
111  return False
112  # Update integrator
113  cur_error_pose = np.array([self.error_pose_euler[0],
114  self.error_pose_euler[1],
115  self.error_pose_euler[2],
116  self.error_pose_euler[5]])
117  self._int += 0.5 * (cur_error_pose + self._error_pose) * self._dt
118  # Store current pose error
119  self._error_pose = cur_error_pose
120  error_vel = np.array([self._errors['vel'][0],
121  self._errors['vel'][1],
122  self._errors['vel'][2],
123  self._errors['vel'][5]])
124  ua_tau = np.dot(self._Kp, cur_error_pose) \
125  + np.dot(self._Kd, error_vel) \
126  + np.dot(self._Ki, self._int)
127  self._tau = np.array([ua_tau[0], ua_tau[1], ua_tau[2], 0, 0, ua_tau[3]])
128  self.publish_control_wrench(self._tau)
129  return True
130 
131 if __name__ == '__main__':
132  print('Starting Underactuated PID Controller')
133  rospy.init_node('rov_ua_pid_controller')
134 
135  try:
137  rospy.spin()
138  except rospy.ROSInterruptException:
139  print('caught exception')
140  print('exiting')


uuv_trajectory_control
Author(s):
autogenerated on Thu Jun 18 2020 03:28:42