Skip to content

Commit ea0912f

Browse files
committed
add support for ship types
1 parent 5361610 commit ea0912f

File tree

2 files changed

+81
-10
lines changed

2 files changed

+81
-10
lines changed

antares-python/src/antares/cli.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
from typing import NoReturn
88

99
import typer
10+
from pydantic import ValidationError
1011
from rich.console import Console
1112
from rich.theme import Theme
1213

13-
from antares import AntaresClient, ShipConfig
14+
from antares import AntaresClient
1415
from antares.config_loader import load_config
1516
from antares.errors import ConnectionError, SimulationError, SubscriptionError
1617
from antares.logger import setup_logging
18+
from antares.models.ship import CircleShip, LineShip, RandomShip, ShipConfig, StationaryShip
1719

1820
app = typer.Typer(name="antares-cli", help="Antares CLI for ship simulation", no_args_is_help=True)
1921
console = Console(theme=Theme({"info": "green", "warn": "yellow", "error": "bold red"}))
@@ -86,21 +88,45 @@ def reset(
8688

8789

8890
@app.command()
89-
def add_ship(
90-
x: float = typer.Option(..., help="X coordinate of the ship"),
91-
y: float = typer.Option(..., help="Y coordinate of the ship"),
91+
def add_ship( # noqa: PLR0913
92+
type: str = typer.Option(..., help="Type of ship: 'line', 'circle', 'random', or 'stationary'"),
93+
x: float = typer.Option(..., help="Initial X coordinate of the ship"),
94+
y: float = typer.Option(..., help="Initial Y coordinate of the ship"),
95+
angle: float = typer.Option(None, help="(line) Movement angle in radians"),
96+
speed: float = typer.Option(None, help="(line/circle) Constant speed"),
97+
radius: float = typer.Option(None, help="(circle) Radius of the circular path"),
98+
max_speed: float = typer.Option(None, help="(random) Maximum possible speed"),
9299
config: str = typer.Option(None, help="Path to the TOML configuration file"),
93100
verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose output"),
94101
json_output: bool = typer.Option(False, "--json", help="Output in JSON format"),
95102
) -> None:
96103
"""
97-
Add a ship to the simulation with the specified parameters.
104+
Add a ship to the simulation, specifying its motion pattern and parameters.
98105
"""
99106
client = build_client(config, verbose, json_output)
107+
108+
base_args = {"initial_position": (x, y)}
109+
110+
ship: ShipConfig | None = None
111+
try:
112+
if type == "line":
113+
ship = LineShip(**base_args, angle=angle, speed=speed) # type: ignore[arg-type]
114+
elif type == "circle":
115+
ship = CircleShip(**base_args, radius=radius, speed=speed) # type: ignore[arg-type]
116+
elif type == "random":
117+
ship = RandomShip(**base_args, max_speed=max_speed) # type: ignore[arg-type]
118+
elif type == "stationary":
119+
ship = StationaryShip(**base_args) # type: ignore[arg-type]
120+
else:
121+
raise ValueError(f"Invalid ship type: {type!r}")
122+
123+
except (ValidationError, ValueError, TypeError) as e:
124+
handle_error(f"Invalid ship parameters: {e}", code=2, json_output=json_output)
125+
return
126+
100127
try:
101-
ship = ShipConfig(initial_position=(x, y))
102128
client.add_ship(ship)
103-
msg = f"🚢 Added ship at ({x}, {y})"
129+
msg = f"🚢 Added {type} ship at ({x}, {y})"
104130
typer.echo(json.dumps({"message": msg}) if json_output else msg)
105131
except (ConnectionError, SimulationError) as e:
106132
handle_error(str(e), code=2, json_output=json_output)
Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,56 @@
1+
from typing import Annotated, Literal
2+
13
from pydantic import BaseModel, Field
24

35

4-
class ShipConfig(BaseModel):
6+
class BaseShip(BaseModel):
57
"""
6-
Defines the configuration for a ship to be added to the simulation.
8+
Base class for ship configurations.
79
"""
810

911
initial_position: tuple[float, float] = Field(
10-
..., description="Initial (x, y) coordinates of the ship in simulation space."
12+
..., description="Initial (x, y) coordinates of the ship."
1113
)
14+
15+
16+
class LineShip(BaseShip):
17+
"""
18+
Ship that moves in a straight line at a constant speed.
19+
"""
20+
21+
type: Literal["line"] = "line"
22+
angle: float = Field(..., description="Angle in radians.")
23+
speed: float = Field(..., description="Constant speed.")
24+
25+
26+
class CircleShip(BaseShip):
27+
"""
28+
Ship that moves in a circular path at a constant speed.
29+
"""
30+
31+
type: Literal["circle"] = "circle"
32+
radius: float = Field(..., description="Radius of circular path.")
33+
speed: float = Field(..., description="Constant speed.")
34+
35+
36+
class RandomShip(BaseShip):
37+
"""
38+
Ship that moves in a random direction at a constant speed.
39+
"""
40+
41+
type: Literal["random"] = "random"
42+
max_speed: float = Field(..., description="Maximum possible speed.")
43+
44+
45+
class StationaryShip(BaseShip):
46+
"""
47+
Ship that does not move.
48+
"""
49+
50+
type: Literal["stationary"] = "stationary"
51+
52+
53+
# Union of all ship configs
54+
ShipConfig = Annotated[
55+
LineShip | CircleShip | RandomShip | StationaryShip, Field(discriminator="type")
56+
]

0 commit comments

Comments
 (0)