Spaces:
Running
Running
from pydantic import BaseModel, Field | |
from typing import Dict, List, Optional, Any, Literal | |
from datetime import datetime | |
from enum import Enum | |
# ============= ROBOT COMMAND MODELS ============= | |
class JointUpdate(BaseModel): | |
name: str | |
value: float | |
speed: Optional[float] = None | |
class RobotCommand(BaseModel): | |
timestamp: int | |
joints: List[JointUpdate] | |
duration: Optional[int] = None | |
metadata: Optional[Dict[str, Any]] = None | |
class CommandSequence(BaseModel): | |
id: str | |
name: str | |
commands: List[RobotCommand] | |
loop: Optional[bool] = False | |
total_duration: int | |
# ============= COMMUNICATION MODELS ============= | |
class ControlMessage(BaseModel): | |
type: Literal["command", "sequence", "heartbeat", "status_request"] | |
timestamp: str | |
data: Optional[Dict[str, Any]] = None | |
class StatusMessage(BaseModel): | |
type: Literal["status", "joint_states", "error", "heartbeat_ack", "slave_status"] | |
timestamp: str | |
slave_id: Optional[str] = None | |
data: Optional[Dict[str, Any]] = None | |
# ============= ROBOT MODELS ============= | |
class JointLimits(BaseModel): | |
lower: Optional[float] = None | |
upper: Optional[float] = None | |
velocity: Optional[float] = None | |
effort: Optional[float] = None | |
class DriverJointState(BaseModel): | |
name: str | |
servo_id: int | |
type: Literal["revolute", "continuous"] | |
virtual_value: float | |
real_value: Optional[float] = None | |
limits: Optional[JointLimits] = None | |
class ConnectionStatus(BaseModel): | |
is_connected: bool | |
last_connected: Optional[datetime] = None | |
error: Optional[str] = None | |
# ============= ROBOT MANAGEMENT ============= | |
class Robot(BaseModel): | |
id: str | |
name: str | |
robot_type: str | |
created_at: datetime | |
joints: List[DriverJointState] = [] | |
# Connection state | |
master_connected: bool = False | |
master_connection_id: Optional[str] = None | |
slave_connections: List[str] = [] | |
# Control state | |
last_command_source: Literal["master", "manual", "none"] = "none" | |
last_command_time: Optional[datetime] = None | |
class RobotStatus(BaseModel): | |
robot_id: str | |
master_connected: bool | |
slave_count: int | |
last_command_source: str | |
last_command_time: Optional[datetime] | |
last_seen: datetime | |
class CreateRobotRequest(BaseModel): | |
name: Optional[str] = None | |
robot_type: str = "so-arm100" | |
# ============= DEMO SEQUENCES ============= | |
DEMO_SEQUENCES = [ | |
CommandSequence( | |
id="gentle-wave", | |
name="Gentle Wave Pattern", | |
total_duration=6000, | |
commands=[ | |
RobotCommand( | |
timestamp=0, | |
joints=[ | |
JointUpdate(name="Rotation", value=-10), | |
JointUpdate(name="Pitch", value=8), | |
JointUpdate(name="Elbow", value=-12) | |
], | |
duration=2000 | |
), | |
RobotCommand( | |
timestamp=2000, | |
joints=[JointUpdate(name="Wrist_Roll", value=10)], | |
duration=1000 | |
), | |
RobotCommand( | |
timestamp=3000, | |
joints=[JointUpdate(name="Wrist_Roll", value=-10)], | |
duration=1000 | |
), | |
RobotCommand( | |
timestamp=4000, | |
joints=[ | |
JointUpdate(name="Wrist_Roll", value=0), | |
JointUpdate(name="Rotation", value=0), | |
JointUpdate(name="Pitch", value=0), | |
JointUpdate(name="Elbow", value=0) | |
], | |
duration=2000 | |
) | |
] | |
), | |
CommandSequence( | |
id="small-scan", | |
name="Small Scanning Pattern", | |
total_duration=8000, | |
commands=[ | |
RobotCommand( | |
timestamp=0, | |
joints=[ | |
JointUpdate(name="Rotation", value=-15), | |
JointUpdate(name="Pitch", value=10) | |
], | |
duration=2000 | |
), | |
RobotCommand( | |
timestamp=2000, | |
joints=[JointUpdate(name="Rotation", value=15)], | |
duration=3000 | |
), | |
RobotCommand( | |
timestamp=5000, | |
joints=[ | |
JointUpdate(name="Rotation", value=0), | |
JointUpdate(name="Pitch", value=0) | |
], | |
duration=3000 | |
) | |
] | |
), | |
CommandSequence( | |
id="tiny-flex", | |
name="Tiny Flex Pattern", | |
total_duration=8000, | |
commands=[ | |
RobotCommand( | |
timestamp=0, | |
joints=[ | |
JointUpdate(name="Elbow", value=-15), | |
JointUpdate(name="Wrist_Pitch", value=8) | |
], | |
duration=2000 | |
), | |
RobotCommand( | |
timestamp=2000, | |
joints=[JointUpdate(name="Jaw", value=8)], | |
duration=1000 | |
), | |
RobotCommand( | |
timestamp=3000, | |
joints=[JointUpdate(name="Elbow", value=-25)], | |
duration=2000 | |
), | |
RobotCommand( | |
timestamp=5000, | |
joints=[ | |
JointUpdate(name="Jaw", value=0), | |
JointUpdate(name="Elbow", value=0), | |
JointUpdate(name="Wrist_Pitch", value=0) | |
], | |
duration=3000 | |
) | |
] | |
) | |
] |