Skip to content

Commit bc1614a

Browse files
committed
[#144] Add Hill-frame impulsive thrust
1 parent 3349d63 commit bc1614a

4 files changed

Lines changed: 78 additions & 7 deletions

File tree

docs/source/release_notes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Development - |version|
3333
* Add a maximum range checking dynamics model in :class:`MaxRangeDynModel`. Useful for keeping an agent
3434
in the vicinity of a target early in training.
3535
* Add properties in spacecraft dynamics for orbital element observations.
36-
36+
* Add :class:`ImpulsiveThrustHill` for impulsive thrust the Hill frame.
3737

3838
Version 1.1.0
3939
-------------

src/bsk_rl/act/__init__.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,24 @@ class MyActionSatellite(Satellite):
4545
Use :class:`ContinuousAction` for actions with a continuous action space. Currently, satellites
4646
can only have a single continuous action in their ``action_spec``.
4747
48-
+----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
49-
| **Action** |**Dimension**| **Description** |
50-
+----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
51-
| :class:`ImpulsiveThrust` | 4 | Instantaneously change the satellite's velocity, and drift for some duration. |
52-
+----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
48+
+-----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
49+
| **Action** |**Dimension**| **Description** |
50+
+-----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
51+
| :class:`ImpulsiveThrust` | 4 | Instantaneously change the satellite's velocity, and drift for some duration. |
52+
+-----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
53+
| :class:`ImpulsiveThrustHill`| 4 | Like :class:`ImpulsiveThrust`, but specified in the Hill frame of another satellite. |
54+
+-----------------------------+-------------+-------------------------------------------------------------------------------------------------------+
5355
5456
5557
5658
"""
5759

5860
from bsk_rl.act.actions import Action
59-
from bsk_rl.act.continuous_actions import ContinuousAction, ImpulsiveThrust
61+
from bsk_rl.act.continuous_actions import (
62+
ContinuousAction,
63+
ImpulsiveThrust,
64+
ImpulsiveThrustHill,
65+
)
6066
from bsk_rl.act.discrete_actions import (
6167
Charge,
6268
Desat,
@@ -81,4 +87,5 @@ class MyActionSatellite(Satellite):
8187
"Scan",
8288
"ContinuousAction",
8389
"ImpulsiveThrust",
90+
"ImpulsiveThrustHill",
8491
]

src/bsk_rl/act/continuous_actions.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,33 @@ def set_action(self, action: np.ndarray) -> None:
154154
if self.fsw_action is not None:
155155
getattr(self.satellite.fsw, self.fsw_action)()
156156
self.satellite.log_info(f"FSW action {self.fsw_action} activated.")
157+
158+
159+
class ImpulsiveThrustHill(ImpulsiveThrust):
160+
def __init__(self, chief_name, *args, **kwargs):
161+
"""Impulsive thrusts in the Hill frame.
162+
163+
Args:
164+
chief_name: Chief to use for Hill frame.
165+
*args: Passed to ``ImpulsiveThrust``.
166+
**kwargs: Passed to ``ImpulsiveThrust``.
167+
"""
168+
self.chief_name = chief_name
169+
super().__init__(*args, **kwargs)
170+
171+
def reset_post_sim_init(self) -> None:
172+
"""Connect to the chief satellite.
173+
174+
:meta private:
175+
"""
176+
self.chief = self.satellite.simulator.get_satellite(self.chief_name)
177+
178+
def set_action(self, action: np.ndarray) -> None:
179+
"""Activate the action by setting the continuous value."""
180+
dv_H = action[0:3]
181+
dt = action[3]
182+
183+
NH = self.chief.dynamics.HN.T
184+
dv_N = NH @ dv_H
185+
186+
super().set_action(np.concatenate((dv_N, [dt])))

tests/integration/act/test_int_actions_continuous.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from bsk_rl import act, obs, sats
66
from bsk_rl.sim import dyn, fsw
7+
from bsk_rl.utils.orbital import random_orbit
78

89

910
class TestImpulsiveThrust:
@@ -34,3 +35,36 @@ def test_thrust(self):
3435
self.env.step([0.0, 0.0, 0.0, 5.0])
3536
time_after = self.env.unwrapped.simulator.sim_time
3637
assert time_after - time_before == approx(5.0)
38+
39+
40+
class TestHillImpulsiveThrust:
41+
class ThrustSat(sats.Satellite):
42+
dyn_type = dyn.BasicDynamicsModel
43+
fsw_type = fsw.MagicOrbitalManeuverFSWModel
44+
observation_spec = [obs.SatProperties(dict(prop="v_BN_N"))]
45+
action_spec = [act.ImpulsiveThrustHill(chief_name="ThrusterSat")]
46+
47+
env = gym.make(
48+
"SatelliteTasking-v1",
49+
satellite=ThrustSat(
50+
"ThrusterSat",
51+
sat_args=dict(
52+
dv_available_init=1000.0,
53+
oe=random_orbit(i=0.0, e=0.0, Omega=0.0, omega=0.0, f=90.0),
54+
),
55+
),
56+
sim_rate=0.01,
57+
time_limit=10000.0,
58+
disable_env_checker=True,
59+
)
60+
61+
def test_thrust(self):
62+
observation_before, _ = self.env.reset()
63+
observation_after, _, _, _, _ = self.env.step([100.0, 0.0, 0.0, 0.02])
64+
diff = observation_after - observation_before
65+
assert np.allclose(diff, np.array([0.0, 100.0, 0.0]), atol=0.5)
66+
67+
time_before = self.env.unwrapped.simulator.sim_time
68+
self.env.step([0.0, 0.0, 0.0, 5.0])
69+
time_after = self.env.unwrapped.simulator.sim_time
70+
assert time_after - time_before == approx(5.0)

0 commit comments

Comments
 (0)