Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization Controller for Review #23

Merged
merged 113 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
8a4eae3
Add trinary thruster controller layer
AndrewHWang1605 Jan 17, 2024
77857b7
Add framework for optimization python node
AndrewHWang1605 Jan 17, 2024
07b0fd0
Add sim opt launch
AndrewHWang1605 Jan 17, 2024
0f1ff0b
Small changes on VM
AndrewHWang1605 Jan 18, 2024
eab4bac
Tweak Cmakelists
AndrewHWang1605 Jan 18, 2024
de53d63
Test thruster commands sending from optimization controller node
AndrewHWang1605 Jan 18, 2024
be63b77
Remove PWM controller from running
AndrewHWang1605 Jan 18, 2024
3f4bccb
Convert magic number constants into ROS parameters
AndrewHWang1605 Jan 19, 2024
3626bb9
Merge
AndrewHWang1605 Jan 19, 2024
583fb81
Ported over optimization controller into opt_ctrl_py_node
AndrewHWang1605 Jan 19, 2024
9f61e71
Debugging checkpoint
AndrewHWang1605 Jan 19, 2024
db4360b
Small changes
AndrewHWang1605 Jan 19, 2024
d1f9dae
Add flag and callback to handle loading of parameters after initializ…
AndrewHWang1605 Jan 19, 2024
e79289e
Add parameterization of goal
AndrewHWang1605 Jan 19, 2024
3423456
Debugging ROS params
AndrewHWang1605 Jan 20, 2024
767792f
Temporary hardcode params for testing
AndrewHWang1605 Jan 22, 2024
885de59
Fix setting goal as parameter
AndrewHWang1605 Jan 23, 2024
c03516b
Try diff syntax for accessing ROS params
AndrewHWang1605 Jan 23, 2024
fc52d44
Running in ROS stack, performance not great
AndrewHWang1605 Jan 23, 2024
702c89b
Tuning gains
AndrewHWang1605 Jan 23, 2024
ddbd7dc
Add metrics
AndrewHWang1605 Jan 25, 2024
d97d7af
Merge branch 'andrew/optimization_controller' of https://github.com/S…
AndrewHWang1605 Jan 25, 2024
452e238
Add metrics code
AndrewHWang1605 Jan 25, 2024
2ee2428
Tuning controller
AndrewHWang1605 Jan 25, 2024
ff05abd
Controller running on Europa
AndrewHWang1605 Jan 31, 2024
e220ad3
Add controller for close proximity
AndrewHWang1605 Feb 2, 2024
31ed7f2
Continue tuning for orientation precision
AndrewHWang1605 Feb 2, 2024
c667d07
Gain-scheduled controller works decently
AndrewHWang1605 Feb 2, 2024
f50402e
Merge branch 'andrew/optimization_controller' into test_optimization_…
alvinsunyixiao Feb 2, 2024
2bf6bfe
Merge branch 'alvin/binary_thrust_driver' into test_optimization_ctrl
alvinsunyixiao Feb 3, 2024
2c37833
add hardware launch
alvinsunyixiao Feb 3, 2024
b89a271
Merge remote-tracking branch 'origin/alvin/binary_thrust_driver' into…
alvinsunyixiao Feb 5, 2024
a8c6110
Merge fix to ff_drivers CMakeLists to include thruster_node
alvinsunyixiao Feb 5, 2024
09f3ad4
Clean up launch files
AndrewHWang1605 Feb 5, 2024
4d31e56
Clean up files
AndrewHWang1605 Feb 5, 2024
71496c0
Wrap sim state to between -pi and pi, further tuning of close control…
AndrewHWang1605 Feb 8, 2024
f6df0f3
Fix small bugs, some small tuning
AndrewHWang1605 Feb 8, 2024
66d9b07
Code style fixed
AndrewHWang1605 Feb 8, 2024
df7d1c9
still fixing angular tracking and added test file
AndrewHWang1605 Feb 8, 2024
dcc1c76
Changed cost function and tuned gains for angular tracking to work mu…
AndrewHWang1605 Feb 11, 2024
e35eb5e
working decently!
AndrewHWang1605 Feb 11, 2024
9e4529d
Quite nice convergence
AndrewHWang1605 Feb 11, 2024
d4b5427
Passed tests!
AndrewHWang1605 Feb 11, 2024
924ca74
Tune gains for more coasting time
AndrewHWang1605 Feb 13, 2024
825d5b2
Merge branch 'andrew/tuning_optimization_ctrl' into test_optimization…
AndrewHWang1605 Feb 13, 2024
e53c029
add casadi dep
alvinsunyixiao Feb 14, 2024
22adbf4
format code
alvinsunyixiao Feb 14, 2024
d9144f7
Merge remote-tracking branch 'origin/main' into andrew/optimization_c…
alvinsunyixiao Feb 14, 2024
4c5564f
Broke something
AndrewHWang1605 Feb 16, 2024
1bd3a8f
Fixed setup/build issue
AndrewHWang1605 Feb 16, 2024
92cbb27
New metrics node is working!
AndrewHWang1605 Feb 16, 2024
7e0a472
Merge branch 'andrew/optimization_controller' into andrew/metrics
AndrewHWang1605 Feb 16, 2024
110cfb9
Reformat code
AndrewHWang1605 Feb 16, 2024
ffd86d4
Merge branch 'andrew/optimization_controller' into test_optimization_…
AndrewHWang1605 Feb 16, 2024
5497b3c
Add plotjuggler template file for data visualization and logging
AndrewHWang1605 Feb 16, 2024
3272634
Adding manual goal injection
AndrewHWang1605 Feb 17, 2024
7d50e33
reformat code with updated black
AndrewHWang1605 Feb 17, 2024
b8a96fd
Merge branch 'andrew/optimization_controller' of https://github.com/S…
alvinsunyixiao Feb 18, 2024
164e034
Goal testing setup works, added mocap plot juggler, change launch fil…
alvinsunyixiao Feb 18, 2024
ca1ff70
Some hardware tuning
alvinsunyixiao Feb 20, 2024
a9bdc1f
More fruitless tuning
alvinsunyixiao Feb 20, 2024
63cb2a2
Further tuning of gains
alvinsunyixiao Mar 11, 2024
af17d80
Change test location and tune gains
alvinsunyixiao Mar 12, 2024
1f04b4b
Clean up a bit before merging
AndrewHWang1605 Mar 13, 2024
bbe2697
Merge branch 'test_optimization_ctrl' into andrew/optimization_contro…
AndrewHWang1605 Mar 13, 2024
9cf5864
Fix some of Alvin's small comments
AndrewHWang1605 Mar 13, 2024
5d7709c
Merge branch 'andrew/optimization_controller' of https://github.com/S…
alvinsunyixiao Mar 13, 2024
edb0e83
Address Alvin's feedback, remove unnecessary code, add some documenta…
alvinsunyixiao Mar 13, 2024
2dc39c7
Change to two sets of params for close and default controller, works …
alvinsunyixiao Mar 14, 2024
604eb19
Further tuning
alvinsunyixiao Mar 14, 2024
1daa491
Add unpacking rosbag script
AndrewHWang1605 Mar 14, 2024
b1f89dc
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Mar 14, 2024
00f1bbc
Flesh out and test unpack ROSBag functionality
alvinsunyixiao Mar 14, 2024
ad2eda7
New idea penalizing position error and velocity much higher works muc…
alvinsunyixiao Mar 14, 2024
9894a47
Flesh out some functionality on the ROSBag plotter
alvinsunyixiao Mar 14, 2024
2169e51
Start adding calculations of some metrics
alvinsunyixiao Mar 14, 2024
ed5a687
Can plot multiple experiments with script, turnaround and short test …
alvinsunyixiao Mar 14, 2024
b1323e9
More plotting, long distance done
alvinsunyixiao Mar 15, 2024
52fc562
Continue fleshing out metrics calculations, add data from nominal exp…
alvinsunyixiao Mar 15, 2024
78eb3d8
Finish implementing metrics
AndrewHWang1605 Mar 15, 2024
b8a5ff1
Add more metrics to unpackRosbag
AndrewHWang1605 Mar 15, 2024
f1df889
Replace with new data
alvinsunyixiao Mar 15, 2024
4ddbb97
Add new metrics
AndrewHWang1605 Mar 15, 2024
575893c
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Mar 15, 2024
373e74f
Add new pd long data
alvinsunyixiao Mar 15, 2024
7e3f716
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Mar 15, 2024
b1b51ad
Add another opt long
alvinsunyixiao Mar 15, 2024
0a90354
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Mar 15, 2024
c767633
Last optimization long
alvinsunyixiao Mar 15, 2024
f898015
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Mar 15, 2024
7d72d66
Change Fmax per actuator to 0.25 based on empirical testing
AndrewHWang1605 Apr 25, 2024
33e7bf6
Revert "Change Fmax per actuator to 0.25 based on empirical testing"
AndrewHWang1605 Apr 25, 2024
e511518
Commit changes to testing scripts
AndrewHWang1605 Apr 25, 2024
cfd0186
Merge branch 'test_optimization_ctrl' of https://github.com/StanfordA…
AndrewHWang1605 Apr 25, 2024
22238c8
Merge branch 'test_optimization_ctrl' into andrew/optimization_contro…
AndrewHWang1605 Apr 25, 2024
7216c46
Stop tracking experiment data files
AndrewHWang1605 Apr 25, 2024
7f7f06a
Modify gitignore to ignore data files
AndrewHWang1605 Apr 25, 2024
df43315
Consolidate testing files
AndrewHWang1605 Apr 25, 2024
32b6504
Reformatted code with black
AndrewHWang1605 Apr 25, 2024
0748328
Add documentation onto controller metrics node
AndrewHWang1605 Apr 25, 2024
a74c10d
Reformatted code with black
AndrewHWang1605 Apr 25, 2024
fd55bdf
Move state2vec and vec2state to a utility file, removed copy-pasted code
AndrewHWang1605 Apr 30, 2024
1ad0e2e
Remove unused l1-norm helper function
AndrewHWang1605 Apr 30, 2024
1b1fd74
Update ff_sim/ff_sim/controller_metrics.py
AndrewHWang1605 Apr 30, 2024
3c20d70
Update ff_sim/ff_sim/controller_metrics.py
AndrewHWang1605 Apr 30, 2024
8fc30aa
Update ff_control/scripts/opt_ctrl_py_node
AndrewHWang1605 Apr 30, 2024
dd418df
Remove old commented-out code
AndrewHWang1605 Apr 30, 2024
59d8dba
Merge branch 'andrew/optimization_controller' of https://github.com/S…
AndrewHWang1605 Apr 30, 2024
b4bff61
Remove unpack rosbag for this PR
AndrewHWang1605 May 2, 2024
6bbd2d7
Renamed inject goal pose
AndrewHWang1605 May 2, 2024
333a9d3
Change rolling average calculator to use queues
AndrewHWang1605 May 2, 2024
b2345dc
Debugged queue-based rolling average metrics
AndrewHWang1605 May 2, 2024
3f20cb7
Fixed bug in warm start
AndrewHWang1605 May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ __pycache__/
# Distribution / packaging
.Python
build/
install/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
log/
parts/
sdist/
var/
Expand Down Expand Up @@ -131,3 +133,6 @@ dmypy.json

# Pyre type checker
.pyre/

# Data from Free-Flyer low-level MPC characterization experiments (Andrew Wang, 2024)
testing_files/experiment_data
1 change: 1 addition & 0 deletions ff_control/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ ament_python_install_package(${PROJECT_NAME})

# install Python nodes
install(PROGRAMS
scripts/opt_ctrl_py_node
scripts/pd_ctrl_py_node
scripts/safety_filter
DESTINATION lib/${PROJECT_NAME}
Expand Down
42 changes: 3 additions & 39 deletions ff_control/ff_control/linear_ctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from ff_msgs.msg import FreeFlyerState
from ff_msgs.msg import FreeFlyerStateStamped
from ff_msgs.msg import Wrench2D
from ff_control.utils import state2vec

import numpy as np

Expand Down Expand Up @@ -88,9 +89,9 @@ def send_control(self, state_des: T.Union[FreeFlyerState, np.ndarray], K: np.nda

# convert desired state to vector form
if isinstance(state_des, FreeFlyerState):
state_des = self.state2vec(state_des)
state_des = state2vec(state_des)

state_vector = self.state2vec(self.get_state())
state_vector = state2vec(self.get_state())
state_delta = state_des - state_vector
# wrap angle delta to [-pi, pi]
state_delta[2] = (state_delta[2] + np.pi) % (2 * np.pi) - np.pi
Expand All @@ -111,43 +112,6 @@ def state_ready_callback(self) -> None:
"""
pass

@staticmethod
def state2vec(state: FreeFlyerState) -> np.ndarray:
"""
Convert state message to state vector.

:param state: state message
:return: state vector
"""
return np.array(
[
state.pose.x,
state.pose.y,
state.pose.theta,
state.twist.vx,
state.twist.vy,
state.twist.wz,
]
)

@staticmethod
def vec2state(vec: np.ndarray) -> FreeFlyerState:
"""
Convert state vector to state message.

:param vec: state vector
:return: state message
"""
state = FreeFlyerState()
state.pose.x = vec[0]
state.pose.y = vec[1]
state.pose.theta = vec[2]
state.twist.vx = vec[3]
state.twist.vy = vec[4]
state.twist.wz = vec[5]

return state

def state_is_ready(self) -> bool:
"""
Check if state is ready.
Expand Down
11 changes: 9 additions & 2 deletions ff_control/ff_control/ll_ctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, node_name: str = "ll_ctrl_node") -> None:
super().__init__(node_name)

# robot parameters that can be accessed by sub-classes
self.p = RobotParams(self)
self.p = RobotParams(self, self.param_update_callback)

# low level thruster control publishers
self._thruster_binary_pub = self.create_publisher(ThrusterCommand, "ctrl/binary_thrust", 10)
Expand Down Expand Up @@ -76,11 +76,18 @@ def set_wheel_velocity(self, velocity: float) -> None:
"""
Send command to set the inertial wheel velocity.

TODO(alvin): suppor this or remove?
TODO(alvin): support this or remove?

:param velocity: angular velocity in [rad/s]
"""
msg = WheelVelCommand()
msg.header.stamp = self.get_clock().now().to_msg()
msg.velocity = velocity
self._wheel_pub.publish(msg)

def param_update_callback(self):
"""
Callback when parameters are initialized
Override in subclass
"""
pass
76 changes: 76 additions & 0 deletions ff_control/ff_control/tri_thruster_ctrl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# MIT License
#
# Copyright (c) 2024 Stanford Autonomous Systems Lab
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from ff_control.ll_ctrl import LowLevelController
from ff_msgs.msg import ThrusterCommand

import numpy as np
import typing as T


class TrinaryThrusterController(LowLevelController):
def __init__(self, node_name: str = "tri_thruster_ctrl_node") -> None:
super().__init__(node_name)

def set_tri_thrusters(self, tri_switches: T.Sequence[int], use_wheel: bool = False) -> None:
"""
Convert trinary thruster commands into binary thruster commands
This formulation represents each thruster pair (eg thruster 1 and 2 below) as a single
"trinary" thruster, which can either take value -1 (1 on 2 off), 0 (both off), or 1 (1 off 2 on)
This reduces the search space for the optimization, and implicitly removes consideration of the
undesirable case where both thrusters are on (0 net force or moment, only wasted fuel)
tri_switches[0] = Thruster Pair [1,2]
tri_switches[1] = Thruster Pair [3,4]
tri_switches[2] = Thruster Pair [5,6]
tri_switches[3] = Thruster Pair [7,0]


Thrusters Configuration
(2) e_y (1) ___
<-- ^ --> / \
^ | | | ^ v M )
(3)|--o-------o--|(0) __/
| free- |
| flyer | ---> e_x
| robot |
(4)|--o-------o--|(7)
v | | v
<-- -->
(5) (6)
"""

if len(tri_switches) != len(ThrusterCommand().switches) / 2:
self.get_logger().error("Incompatible thruster length sent." + str(len(tri_switches)))
return

switches = []
for i in range(len(tri_switches)):
if tri_switches[i] > 0:
switches.extend([True, False])
elif tri_switches[i] == 0:
switches.extend([False, False])
else:
switches.extend([False, True])
lastVal = switches.pop(-1)
switches = [lastVal] + switches

self.set_thrust_binary(switches)
62 changes: 62 additions & 0 deletions ff_control/ff_control/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# MIT License
#
# Copyright (c) 2024 Stanford Autonomous Systems Lab
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import numpy as np
from ff_msgs.msg import FreeFlyerState


##################### Helper Functions to unpack FreeFlyerState #####################
def state2vec(state: FreeFlyerState) -> np.ndarray:
"""
Convert state message to state vector.

:param state: state message
:return: state vector
"""
return np.array(
[
state.pose.x,
state.pose.y,
state.pose.theta,
state.twist.vx,
state.twist.vy,
state.twist.wz,
]
)


def vec2state(vec: np.ndarray) -> FreeFlyerState:
"""
Convert state vector to state message.

:param vec: state vector
:return: state message
"""
state = FreeFlyerState()
state.pose.x = vec[0]
state.pose.y = vec[1]
state.pose.theta = vec[2]
state.twist.vx = vec[3]
state.twist.vy = vec[4]
state.twist.wz = vec[5]

return state
2 changes: 1 addition & 1 deletion ff_control/ff_control/wrench_ctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def set_body_wrench(self, wrench_body: Wrench2D, use_wheel: bool = False) -> Non
Set wrench in body frame.

:param wrench_body: wrench in body frame
:param use_wheel: set to ture to use the inertial wheel (TODO(alvin): unsupported)
:param use_wheel: set to true to use the inertial wheel (TODO(alvin): unsupported)
"""
if use_wheel:
self.get_logger().error("set_wrench failed: use_wheel not implemented")
Expand Down
2 changes: 2 additions & 0 deletions ff_control/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<depend>rclpy</depend>
<depend>geometry_msgs</depend>

<exec_depend>casadi-pip</exec_depend>

<depend>ff_estimate</depend>
<depend>ff_msgs</depend>
<depend>ff_params</depend>
Expand Down
Loading
Loading