Source code for state_space_setup_assistant.session
"""In-memory wizard state.
One WizardSession per server process (single local user). Two browser tabs
against the same server share and clobber this state -- documented limitation.
"""
import atexit
import shutil
import tempfile
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
[docs]
@dataclass
class WizardSession:
urdf_source: Optional[str] = None # what the user typed (kept for export)
urdf_path: Optional[str] = None # resolved absolute path
urdf_xml: Optional[str] = None # xacro-processed XML (what the viewer gets)
robot_name: Optional[str] = None
joints: List[Any] = field(default_factory=list) # list[JointInfo]
validation: List[Dict] = field(default_factory=list)
model_cfg: Optional[Dict] = None # last model.yaml dict (yamlgen output)
model: Any = None # StateSpaceModel
design_cfg: Optional[Dict] = None # last design.yaml dict
result: Any = None # ControllerResult
benchmark: Optional[Dict] = None # last benchmark response
output_dir: Optional[str] = None # default export dir from --output-dir
# Cached JSON payloads of the last successful call per step, so a browser
# reload can rehydrate the wizard via GET /api/state.
responses: Dict[str, Dict] = field(default_factory=dict)
workdir: str = field(default_factory=lambda: tempfile.mkdtemp(
prefix='ss_setup_'))
def __post_init__(self):
atexit.register(shutil.rmtree, self.workdir, ignore_errors=True)
[docs]
def reset_robot(self):
"""Clear everything derived from a previously loaded robot."""
self.urdf_source = None
self.urdf_path = None
self.urdf_xml = None
self.robot_name = None
self.joints = []
self.validation = []
self.reset_model()
[docs]
def reset_model(self):
"""Clear everything derived from a previous linearization."""
self.model_cfg = None
self.model = None
self.design_cfg = None
self.result = None
self.benchmark = None
for key in ('linearize', 'design', 'benchmark', 'export'):
self.responses.pop(key, None)