dpang commited on
Commit
d7b1511
·
verified ·
1 Parent(s): 151d11e

Add models.py

Browse files
Files changed (1) hide show
  1. models.py +132 -0
models.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Space Robotics Lab, SnT, University of Luxembourg, SpaceR
2
+ # RANS: arXiv:2310.07393 — OpenEnv-compatible implementation
3
+
4
+ """
5
+ models.py
6
+ ---------
7
+ Action, Observation, and State dataclasses for the RANS spacecraft environment.
8
+
9
+ These follow the OpenEnv conventions (openenv-core):
10
+ Action — sent by the RL agent / client to the server
11
+ Observation — returned by the server after reset() / step()
12
+ State — persistent episode metadata readable via /state
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Any, Dict, List
18
+
19
+ try:
20
+ from openenv.core.env_server.interfaces import Action, Observation, State
21
+ except ImportError:
22
+ # Fallback for standalone development / testing without openenv-core
23
+ from pydantic import BaseModel as Action # type: ignore[assignment]
24
+ from pydantic import BaseModel as Observation # type: ignore[assignment]
25
+ from pydantic import BaseModel as State # type: ignore[assignment]
26
+
27
+
28
+ # ---------------------------------------------------------------------------
29
+ # Action
30
+ # ---------------------------------------------------------------------------
31
+
32
+ class SpacecraftAction(Action):
33
+ """
34
+ Control action for the RANS spacecraft.
35
+
36
+ ``thrusters`` is a list of activations, one per thruster, each in [0, 1].
37
+ For binary (on/off) control pass values of 0.0 or 1.0.
38
+ The list length should match the thruster count of the configured platform
39
+ (8 for the default MFP2D layout).
40
+
41
+ Example (8-thruster, fire thruster 0 only)::
42
+
43
+ SpacecraftAction(thrusters=[1, 0, 0, 0, 0, 0, 0, 0])
44
+ """
45
+
46
+ thrusters: List[float]
47
+
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # Observation
51
+ # ---------------------------------------------------------------------------
52
+
53
+ class SpacecraftObservation(Observation):
54
+ """
55
+ Full observation returned after each ``reset()`` / ``step()``.
56
+
57
+ Fields
58
+ ------
59
+ state_obs : List[float]
60
+ Task-specific state vector (6–8 floats depending on task).
61
+ Content varies per task — see individual task docstrings.
62
+
63
+ thruster_transforms : List[List[float]]
64
+ Shape [n_thrusters × 5]. Each row: [px, py, dx, dy, force_max].
65
+ Encodes the physical layout of thrusters on the platform.
66
+
67
+ thruster_masks : List[float]
68
+ Binary mask [n_thrusters]. 1.0 = thruster slot is occupied.
69
+
70
+ mass : float
71
+ Platform mass in kg.
72
+
73
+ inertia : float
74
+ Moment of inertia about the yaw axis (kg·m²).
75
+
76
+ task : str
77
+ Active task name, e.g. "GoToPosition".
78
+
79
+ reward : float
80
+ Scalar reward for the most recent step (0.0 after reset).
81
+
82
+ done : bool
83
+ True when the episode has ended (goal reached or step limit).
84
+
85
+ info : Dict[str, Any]
86
+ Task-specific diagnostics, e.g. position_error, goal_reached.
87
+ """
88
+
89
+ state_obs: List[float] = []
90
+ thruster_transforms: List[List[float]] = []
91
+ thruster_masks: List[float] = []
92
+ mass: float = 10.0
93
+ inertia: float = 0.50
94
+ task: str = "GoToPosition"
95
+ reward: float = 0.0
96
+ done: bool = False
97
+ info: Dict[str, Any] = {}
98
+
99
+
100
+ # ---------------------------------------------------------------------------
101
+ # State
102
+ # ---------------------------------------------------------------------------
103
+
104
+ class SpacecraftState(State):
105
+ """
106
+ Persistent episode state (accessible via GET /state).
107
+
108
+ Tracks the spacecraft's physical state and current task configuration
109
+ so that observers (dashboards, loggers) can monitor the episode without
110
+ participating in the step loop.
111
+
112
+ Note: ``episode_id`` and ``step_count`` are inherited from
113
+ ``openenv.core.env_server.interfaces.State`` when openenv-core is
114
+ installed. They are also declared here explicitly so the class works
115
+ as a standalone Pydantic model without openenv-core.
116
+ """
117
+
118
+ # Fields also present in the openenv-core State base class
119
+ episode_id: str = ""
120
+ step_count: int = 0
121
+
122
+ task: str = "GoToPosition"
123
+ # Physical state
124
+ x: float = 0.0
125
+ y: float = 0.0
126
+ heading_rad: float = 0.0
127
+ vx: float = 0.0
128
+ vy: float = 0.0
129
+ angular_velocity_rads: float = 0.0
130
+ # Episode metadata
131
+ total_reward: float = 0.0
132
+ goal_reached: bool = False