Skip to content

Commit 9c27227

Browse files
committed
Servo: rename autotune script
- Support multiple versions of Gazebo. - Add command line options. Signed-off-by: Rhys Mainwaring <rhys.mainwaring@me.com>
1 parent 91f2c7b commit 9c27227

1 file changed

Lines changed: 84 additions & 20 deletions

File tree

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""
22
Script to autotune the PIDs of a joint position controller using Ziegler-Nichols method
33
4+
Run this script
5+
46
57
Bridge topics from Gazebo to ROS 2
68
@@ -10,21 +12,64 @@
1012

1113
import math
1214
import numpy as np
15+
import os
1316
import time
1417
from typing import List, Tuple
1518

16-
from gz.msgs11.clock_pb2 import Clock
17-
from gz.msgs11.double_pb2 import Double
18-
from gz.msgs11.model_pb2 import Model
19-
from gz.transport14 import Node
19+
from argparse import ArgumentParser
20+
21+
# from ardupilot_gazebo.scripts.pid_params import set_param, InvalidParameterError
22+
from pid_params import set_param, InvalidParameterError
23+
24+
# World and model defaults
25+
DEFAULT_WORLD = "servo"
26+
DEFAULT_MODEL = "servo"
27+
DEFAULT_JOINT = "servo_arm_joint"
28+
DEFAULT_CONTROLLER = "JointPositionController"
29+
DEFAULT_TIMEOUT_MS = 1000
30+
31+
# Supported Gazebo versions
32+
GZ_VERSION_GARDEN = "garden"
33+
GZ_VERSION_HARMONIC = "harmonic"
34+
GZ_VERSION_IONIC = "ionic"
35+
36+
37+
def gz_version():
38+
"""Return the environment variable GZ_VERSION if set, else default to 'harmonic'"""
39+
return os.environ.get("GZ_VERSION", GZ_VERSION_HARMONIC)
2040

21-
from ardupilot_gazebo.scripts.pid_params import set_param, InvalidParameterError
41+
42+
if gz_version() == GZ_VERSION_GARDEN:
43+
from gz.msgs9.clock_pb2 import Clock
44+
from gz.msgs9.double_pb2 import Double
45+
from gz.msgs9.model_pb2 import Model
46+
elif gz_version() == GZ_VERSION_HARMONIC:
47+
from gz.msgs10.clock_pb2 import Clock
48+
from gz.msgs10.double_pb2 import Double
49+
from gz.msgs10.model_pb2 import Model
50+
elif gz_version() == GZ_VERSION_IONIC:
51+
from gz.msgs11.clock_pb2 import Clock
52+
from gz.msgs11.double_pb2 import Double
53+
from gz.msgs11.model_pb2 import Model
54+
55+
56+
# Importing gz.transport into the module global scope causes an odd
57+
# multiprocessing conflict with dronecan. This is a workaround.
58+
def gz_node():
59+
if gz_version() == GZ_VERSION_GARDEN:
60+
from gz.transport12 import Node
61+
elif gz_version() == GZ_VERSION_HARMONIC:
62+
from gz.transport13 import Node
63+
elif gz_version() == GZ_VERSION_IONIC:
64+
from gz.transport14 import Node
65+
66+
return Node()
2267

2368

2469
class ClockSubscriber:
2570
def __init__(self):
2671
super().__init__()
27-
self.node = Node()
72+
self.node = gz_node()
2873
self.last_clock = Clock()
2974
self.topic = "/clock"
3075

@@ -51,7 +96,7 @@ def __init__(self, world_name, model_name):
5196
self._world_name = world_name
5297
self._model_name = model_name
5398

54-
self.node = Node()
99+
self.node = gz_node()
55100
self.last_model = Model()
56101

57102
self.subscribe(world_name, model_name)
@@ -93,7 +138,7 @@ class JointCommandPublisher:
93138
def __init__(self, topic: str):
94139
super().__init__()
95140
self.topic = topic
96-
self.node = Node()
141+
self.node = gz_node()
97142
self.pub = self.node.advertise(self.topic, Double)
98143

99144
def set_position(self, position: float):
@@ -102,7 +147,9 @@ def set_position(self, position: float):
102147
self.pub.publish(msg)
103148

104149

105-
class JointAutotuner:
150+
class JointAutotunerGenerated:
151+
"""ML generated auto tuner (not effective)"""
152+
106153
def __init__(
107154
self, world_name: str, model_name: str, joint_name: str, timeout_ms: int = 2000
108155
):
@@ -114,7 +161,7 @@ def __init__(
114161
self.registry = f"/world/{world_name}"
115162
self.prefix = f"JointPositionController.{world_name}.{model_name}.{joint_name}."
116163

117-
self.node = Node()
164+
self.node = gz_node()
118165
self.sample_time = 0.01 # 10ms
119166

120167
self.joint_state_sub = JointStateSubscriber(world_name, model_name)
@@ -211,27 +258,44 @@ def autotune(self) -> Tuple[float, float, float]:
211258
def main():
212259
print("Running autotune")
213260

214-
# Configuration
215-
world_name = "default"
216-
model_name = "joint_position_controller_demo"
217-
joint_name = "j1"
218-
timeout_ms = 1000
261+
# Command line args
262+
parser = ArgumentParser(description="Get controller PIDs")
263+
parser.add_argument("--world", default=DEFAULT_WORLD, type=str, help="world name")
264+
parser.add_argument("--model", default=DEFAULT_MODEL, type=str, help="model name")
265+
parser.add_argument("--joint", default=DEFAULT_JOINT, type=str, help="joint name")
266+
parser.add_argument(
267+
"--controller",
268+
default=DEFAULT_CONTROLLER,
269+
type=str,
270+
help="joint controller system",
271+
)
272+
parser.add_argument(
273+
"--timeout_ms", default=DEFAULT_TIMEOUT_MS, type=str, help="timeout (ms)"
274+
)
275+
args = parser.parse_args()
276+
277+
timeout_ms = args.timeout_ms
278+
279+
world_name = args.world
280+
model_name = args.model
281+
joint_name = args.joint
282+
system_name = args.controller
283+
joint_cmd_topic = f"/model/{args.model}" f"/joint/{args.joint}" f"/0/cmd_pos"
219284

220285
# Create and run autotuner
221286
# tuner = JointAutotuner(world_name, model_name, joint_name, timeout_ms)
222287
# tuner.autotune()
223288

224289
# Create subscribers
225-
clock_sub = ClockSubscriber()
226290
joint_sub = JointStateSubscriber(world_name, model_name)
227291

228292
# Create publishers
229-
joint_cmd = JointCommandPublisher("/rotor_cmd")
293+
joint_cmd = JointCommandPublisher(joint_cmd_topic)
230294

231295
# Dwell period
232296
period = 2.0
233-
limit_max = math.radians(60.0)
234-
limit_min = -math.radians(60.0)
297+
limit_max = math.radians(10.0)
298+
limit_min = -math.radians(0.0)
235299

236300
# control the twitch freqency
237301
start_time = time.monotonic()
@@ -240,7 +304,7 @@ def main():
240304
last_twitch_time = start_time
241305

242306
# control the update rate
243-
update_rate = 100.0
307+
update_rate = 5.0
244308
update_period = 1.0 / update_rate
245309

246310
pos_tgt = 0.0

0 commit comments

Comments
 (0)