Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c919c2c
Add actuator dynamics in TVC and ThrottleControl
chichunwang May 5, 2026
1cf76b8
Refactor actuator_tau parameters to use None as default in TVC and Th…
chichunwang May 5, 2026
cb78b68
Add actuator dynamics to RollControl
chichunwang May 30, 2026
bbc5cd3
Move actuators to a new actuator folder and rename actuator classes
zuorenchen Jun 6, 2026
3656f7e
Refactor roll, throttle, and thrust vector acutator with a new actuat…
zuorenchen Jun 6, 2026
233666b
Add pytest for all actuators
zuorenchen Jun 6, 2026
9892e50
Update rocket.py and flight.py for actuator class update
zuorenchen Jun 6, 2026
f13f92a
Fix actuator class calls
zuorenchen Jun 6, 2026
32bf679
Update active control example with new actuator class
zuorenchen Jun 6, 2026
53e588d
Update time_overshoot in flight.py to align rocketpy commit #45a89
zuorenchen Jun 7, 2026
879a921
Fix actuator unit tests
zuorenchen Jun 14, 2026
a26cd8c
Enhance ThrustVectorActuator2D with serialization methods and improve…
zuorenchen Jun 14, 2026
b3187ed
Fix comment msg
zuorenchen Jun 14, 2026
ee0dcf0
Fix pylint unused parameters
zuorenchen Jun 14, 2026
9f0a956
Remove unused import
zuorenchen Jun 14, 2026
29841c2
Fix pylint warnings
zuorenchen Jun 14, 2026
837e0f4
Refactor __run_in_serial() to fix pylint too much statement warning
zuorenchen Jun 14, 2026
02ba66e
Fix: use warning instead of printf
zuorenchen Jun 14, 2026
8281a6a
Fix comment
zuorenchen Jun 14, 2026
0ec4556
Fix: use warning instead of printf
zuorenchen Jun 14, 2026
4398e40
Run ruff format
zuorenchen Jun 14, 2026
13f53f0
Fix thrust3 and effective_thrust name
zuorenchen Jun 14, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@
" Accelerometer,\n",
" Environment,\n",
" Flight,\n",
" Function,\n",
" GnssReceiver,\n",
" Gyroscope,\n",
" Rocket,\n",
")\n",
"from rocketpy.motors import CylindricalTank, Fluid, HybridMotor\n",
"from rocketpy.motors.tank import MassFlowRateBasedTank\n",
"from rocketpy.tools import quaternions_to_spin\n",
"\n",
"plt.style.use(\"seaborn-v0_8-colorblind\")"
]
Expand Down Expand Up @@ -284,30 +281,36 @@
"outputs": [],
"source": [
"def tvc_controller_function(\n",
" time, sampling_rate, state, state_history, observed_variables, tvc, sensors\n",
" time,\n",
" sampling_rate,\n",
" state,\n",
" state_history,\n",
" observed_variables,\n",
" thrust_vector_control,\n",
" sensors,\n",
"):\n",
" # state = [x, y, z, vx, vy, vz, e0, e1, e2, e3, wx, wy, wz]\n",
"\n",
" # print(time)\n",
"\n",
" tvc.gimbal_angle_x = 0\n",
" tvc.gimbal_angle_y = 0\n",
" thrust_vector_control.gimbal_angle_x = 0\n",
" thrust_vector_control.gimbal_angle_y = 0\n",
" # Return variables of interest to be saved in the observed_variables list\n",
" return (\n",
" time,\n",
" tvc.gimbal_angle_x,\n",
" tvc.gimbal_angle_y,\n",
" thrust_vector_control.gimbal_angle_x,\n",
" thrust_vector_control.gimbal_angle_y,\n",
" )\n",
"\n",
"\n",
"tvc, tvc_controller = HALCYON.add_tvc(\n",
" gimbal_range=10,\n",
"thrust_vector_control, tvc_controller = HALCYON.add_thrust_vector_control(\n",
" controller_function=tvc_controller_function,\n",
" sampling_rate=100,\n",
" max_gimbal_angle=10,\n",
" gimbal_rate_limit=100,\n",
" controller_function=tvc_controller_function,\n",
" return_controller=True,\n",
")\n",
"tvc.info()\n",
"thrust_vector_control.x.info()\n",
"tvc_controller.info()"
]
},
Expand Down Expand Up @@ -373,17 +376,14 @@
" )\n",
"\n",
" # Return variables of interest to be saved in the observed_variables list\n",
" return (\n",
" time,\n",
" roll_control.roll_torque,\n",
" )\n",
" return (time, roll_control.roll_torque, gyro_data, accel_data)\n",
"\n",
"\n",
"roll_control, roll_controller = HALCYON.add_roll_control(\n",
" max_roll_torque=10,\n",
" sampling_rate=100,\n",
" torque_rate_limit=100,\n",
" controller_function=roll_controller_function,\n",
" sampling_rate=100,\n",
" max_roll_torque=10,\n",
" torque_rate_limit=1000,\n",
" return_controller=True,\n",
")\n",
"roll_control.info()\n",
Expand All @@ -408,33 +408,26 @@
" # state = [x, y, z, vx, vy, vz, e0, e1, e2, e3, wx, wy, wz]\n",
"\n",
" # Throttle command: 0.5 Hz sinusoid, centered at 0.8, amplitude 0.2\n",
" throttle_control.throttle = 0.8 + 0.2 * np.sin(2 * np.pi * 0.5 * time)\n",
" throttle_command = 0.8 + 0.2 * np.sin(2 * np.pi * 0.5 * time)\n",
" throttle_control.throttle = throttle_command\n",
" throttle_actual = throttle_control.throttle\n",
"\n",
" # Return variables of interest to be saved in the observed_variables list\n",
" return (\n",
" time,\n",
" throttle_control.throttle,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" throttle_command,\n",
" throttle_actual,\n",
" )\n",
"\n",
"\n",
"throttle_obj, throttle_controller = HALCYON.add_throttle_control(\n",
" controller_function=throttle_controller_function,\n",
" sampling_rate=100,\n",
" throttle_range=(0.0, 1.0),\n",
" throttle_rate_limit=100,\n",
" initial_throttle=1.0,\n",
" throttle_time_constant=0.5,\n",
" return_controller=True,\n",
" clamp=True,\n",
")\n",
"print(\"has add_throttle_control:\", hasattr(HALCYON, \"add_throttle_control\"))\n",
"print(\"has throttle_control:\", hasattr(HALCYON, \"throttle_control\"))\n",
"print(\"throttle_control:\", getattr(HALCYON, \"throttle_control\", None))"
")"
]
},
{
Expand All @@ -461,22 +454,24 @@
" verbose=False,\n",
")\n",
"# test_flight.plots.attitude_data()\n",
"# ===== 先看 throttle 有沒有真的變 =====\n",
"# ===== Plot commanded throttle vs filtered actuator output =====\n",
"obs = np.array(throttle_controller.observed_variables)\n",
"\n",
"t_cmd = obs[:, 0]\n",
"th_cmd = obs[:, 1]\n",
"th_act = obs[:, 2]\n",
"\n",
"plt.figure()\n",
"plt.plot(t_cmd, th_cmd, label=\"Throttle\")\n",
"plt.plot(t_cmd, th_cmd, label=\"Throttle command\")\n",
"plt.plot(t_cmd, th_act, label=\"Filtered throttle\")\n",
"plt.xlabel(\"Time (s)\")\n",
"plt.ylabel(\"Throttle\")\n",
"plt.title(\"Throttle Command\")\n",
"plt.title(\"Throttle Command vs Actuator Output\")\n",
"plt.legend()\n",
"plt.grid()\n",
"plt.show()\n",
"\n",
"# ===== 再看推力有沒有跟著變 =====\n",
"# ===== Then check thrust response =====\n",
"plt.figure()\n",
"plt.plot(\n",
" test_flight.net_thrust[:, 0], test_flight.net_thrust[:, 1], label=\"Effective Thrust\"\n",
Expand All @@ -491,15 +486,6 @@
"time1, ax, ay, az = zip(*accelerometer_clean.measured_data)\n",
"time2, gx, gy, gz = zip(*gyro_clean.measured_data)\n",
"\n",
"# plt.plot(time1, ax, label=\"Accelerometer X\")\n",
"# plt.plot(time1, ay, label=\"Accelerometer Y\")\n",
"# plt.plot(time1, az, label=\"Accelerometer Z\")\n",
"# plt.xlabel(\"Time (s)\")\n",
"# plt.ylabel(\"Acceleration (m/s^2)\")\n",
"# plt.legend()\n",
"# plt.grid()\n",
"# plt.show()\n",
"\n",
"plt.plot(time2, gx, label=\"Gyroscope X\")\n",
"plt.plot(time2, gy, label=\"Gyroscope Y\")\n",
"plt.plot(time2, gz, label=\"Gyroscope Z\")\n",
Expand Down Expand Up @@ -532,7 +518,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": ".venv (3.14.3.final.0)",
"language": "python",
"name": "python3"
},
Expand All @@ -546,7 +532,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
"version": "3.14.3"
}
},
"nbformat": 4,
Expand Down
35 changes: 35 additions & 0 deletions rocketpy/prints/roll_actuator_prints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class _RollActuatorPrints:
"""Class that contains all roll actuator prints."""

def __init__(self, roll_actuator):
"""Initializes _RollActuatorPrints class

Parameters
----------
roll_actuator: rocketpy.RollActuator
Instance of the RollActuator class.

Returns
-------
None
"""
self.roll_actuator = roll_actuator

def basics(self):
"""Prints information of the roll actuator."""
print(f"Information of {self.roll_actuator.name}:")
print("----------------------------------")
print(f"Torque demand rate: {self.roll_actuator.demand_rate} Hz")
print(
f"Torque range: {self.roll_actuator.actuator_range[0]:.2f} to {self.roll_actuator.actuator_range[1]:.2f} N·m"
)
print(f"Torque rate limit: {self.roll_actuator.actuator_rate_limit} N·m/s")
print(
f"Torque clamping: {'Enabled' if self.roll_actuator.clamp else 'Disabled'}"
)
print(f"Torque time constant: {self.roll_actuator.actuator_time_constant} sec")
print(f"Current roll torque: {self.roll_actuator.roll_torque:.2f} N·m")

def all(self):
"""Prints all information of the roll actuator."""
self.basics()
30 changes: 0 additions & 30 deletions rocketpy/prints/roll_control_prints.py

This file was deleted.

35 changes: 35 additions & 0 deletions rocketpy/prints/throttle_actuator_prints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class _ThrottleActuatorPrints:
def __init__(self, throttle_actuator):
"""Initializes _ThrottleActuatorPrints class

Parameters
----------
throttle_actuator: rocketpy.ThrottleActuator
Instance of the ThrottleActuator class.

Returns
-------
None
"""
self.throttle_actuator = throttle_actuator

def basics(self):
"""Prints information of the throttle actuator."""
print(f"Information of {self.throttle_actuator.name}:")
print("----------------------------------")
print(f"Throttle demand rate: {self.throttle_actuator.demand_rate} Hz")
print(
f"Throttle range: {self.throttle_actuator.actuator_range[0]:.2f} to {self.throttle_actuator.actuator_range[1]:.2f}"
)
print(f"Throttle rate limit: {self.throttle_actuator.actuator_rate_limit}")
print(
f"Throttle Clamping: {'Enabled' if self.throttle_actuator.clamp else 'Disabled'}"
)
print(
f"Throttle time constant: {self.throttle_actuator.actuator_time_constant} sec"
)
print(f"Current throttle: {self.throttle_actuator.throttle:.2f}")

def all(self):
"""Prints all information of the throttle actuator."""
self.basics()
15 changes: 0 additions & 15 deletions rocketpy/prints/throttle_control_prints.py

This file was deleted.

41 changes: 41 additions & 0 deletions rocketpy/prints/thrust_vector_actuator_prints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class _ThrustVectorActuatorPrints:
"""Class that contains all thrust vector actuator prints."""

def __init__(self, thrust_vector_actuator):
"""Initializes _ThrustVectorActuatorPrints class

Parameters
----------
thrust_vector_actuator: rocketpy.ThrustVectorActuator
Instance of the thrust vector actuator class.

Returns
-------
None
"""
self.thrust_vector_actuator = thrust_vector_actuator

def basics(self):
"""Prints information of the thrust vector actuator."""
print(f"Information of {self.thrust_vector_actuator.name}:")
print("----------------------------------")
print(f"Gimbal demand rate: {self.thrust_vector_actuator.demand_rate} Hz")
print(
f"Gimbal range: {self.thrust_vector_actuator.actuator_range[0]:.2f} to {self.thrust_vector_actuator.actuator_range[1]:.2f} deg"
)
print(
f"Gimbal rate limit: {self.thrust_vector_actuator.actuator_rate_limit} deg/sec"
)
print(
f"Gimbal clamping: {'Enabled' if self.thrust_vector_actuator.clamp else 'Disabled'}"
)
print(
f"Gimbal time constant: {self.thrust_vector_actuator.actuator_time_constant} sec"
)
print(
f"Current gimbal angle: {self.thrust_vector_actuator.gimbal_angle:.2f} deg"
)

def all(self):
"""Prints all information of the thrust vector actuator."""
self.basics()
29 changes: 0 additions & 29 deletions rocketpy/prints/tvc_prints.py

This file was deleted.

4 changes: 4 additions & 0 deletions rocketpy/rocket/actuator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from rocketpy.rocket.actuator.actuator import Actuator
from rocketpy.rocket.actuator.roll import RollActuator
from rocketpy.rocket.actuator.throttle import ThrottleActuator
from rocketpy.rocket.actuator.thrust_vector import ThrustVectorActuator
Loading
Loading