PositionControlUnderactuated.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (c) 2016 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 
17 import numpy
18 import rospy
19 import tf
20 import tf.transformations as trans
21 from PIDRegulator import PIDRegulator
22 
23 from dynamic_reconfigure.server import Server
24 from uuv_control_cascaded_pid.cfg import PositionControlConfig
25 import geometry_msgs.msg as geometry_msgs
26 from nav_msgs.msg import Odometry
27 from rospy.numpy_msg import numpy_msg
28 
29 
31  def __init__(self):
32  print('PositionControllerNode: initializing node')
33 
34  self.config = {}
35 
36  self.pos_des = numpy.zeros(3)
37  self.quat_des = numpy.array([0, 0, 0, 1])
38 
39  self.initialized = False
40 
41  # Initialize pids with default parameters
42  self.pid_depth = PIDRegulator(1, 0, 0, 1)
43  self.pid_heading = PIDRegulator(1, 0, 0, 1)
44  self.pid_forward = PIDRegulator(1, 0, 0, 1)
45 
46  # ROS infrastructure
48  self.sub_cmd_pose = rospy.Subscriber('cmd_pose', numpy_msg(geometry_msgs.PoseStamped), self.cmd_pose_callback)
49  self.sub_odometry = rospy.Subscriber('odom', numpy_msg(Odometry), self.odometry_callback)
50  self.pub_cmd_vel = rospy.Publisher('cmd_vel', geometry_msgs.Twist, queue_size=10)
51  self.srv_reconfigure = Server(PositionControlConfig, self.config_callback)
52 
53  def cmd_pose_callback(self, msg):
54  """Handle updated set pose callback."""
55  # Just store the desired pose. The actual control runs on odometry callbacks
56  p = msg.pose.position
57  q = msg.pose.orientation
58  self.pos_des = numpy.array([p.x, p.y, p.z])
59  self.quat_des = numpy.array([q.x, q.y, q.z, q.w])
60 
61  def odometry_callback(self, msg):
62  """Handle updated measured velocity callback."""
63  if not bool(self.config):
64  return
65 
66  p = msg.pose.pose.position
67  q = msg.pose.pose.orientation
68  p = numpy.array([p.x, p.y, p.z])
69  q = numpy.array([q.x, q.y, q.z, q.w])
70 
71  if not self.initialized:
72  # If this is the first callback: Store and hold latest pose.
73  self.pos_des = p
74  self.quat_des = q
75  self.initialized = True
76 
77  # Compute control output:
78  t = msg.header.stamp.to_sec()
79 
80  # Position error wrt. body frame
81  e_pos = trans.quaternion_matrix(q).transpose()[0:3,0:3].dot(self.pos_des - p)
82 
83  vz = self.pid_depth.regulate(e_pos[2], t)
84  vx = self.pid_forward.regulate(numpy.linalg.norm(e_pos[0:2]), t)
85  wx = self.pid_heading.regulate(numpy.arctan2(), t)
86 
87  v_linear = numpy.array([vx, 0, vz])
88  v_angular = numpy.array([0, 0, wz])
89 
90  # Convert and publish vel. command:
91  cmd_vel = geometry_msgs.Twist()
92  cmd_vel.linear = geometry_msgs.Vector3(*v_linear)
93  cmd_vel.angular = geometry_msgs.Vector3(*v_angular)
94 
95  self.pub_cmd_vel.publish(cmd_vel)
96 
97  def config_callback(self, config, level):
98  """Handle updated configuration values."""
99  # Config has changed, reset PID controllers
100  self.pid_forward = PIDRegulator(config['forward_p'], config['forward_i'], config['forward_d'], config['forward_sat'])
101  self.pid_depth = PIDRegulator(config['depth_p'], config['depth_i'], config['depth_d'], config['depth_sat'])
102  self.pid_heading = PIDRegulator(config['heading_p'], config['heading_i'], config['heading_d'], config['heading_sat'])
103 
104  self.config = config
105 
106  return config
107 
108 
109 if __name__ == '__main__':
110  print('starting PositionControl.py')
111  rospy.init_node('position_control')
112 
113  try:
115  rospy.spin()
116  except rospy.ROSInterruptException:
117  print('caught exception')
118  print('exiting')


uuv_control_cascaded_pids
Author(s): Musa Morena Marcusso Manhaes , Sebastian Scherer , Luiz Ricardo Douat
autogenerated on Mon Jul 1 2019 19:39:10