113 lines
3.2 KiB
Python
113 lines
3.2 KiB
Python
import uuid
|
|
import logging
|
|
from typing import Any, Callable, Dict, List, Union
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
MorphologyType = Union[str, Callable[[str], List[Dict[str, Any]]]]
|
|
|
|
|
|
def generate_id() -> str:
|
|
return uuid.uuid4().hex
|
|
|
|
|
|
def get_InitSensor(morphology: MorphologyType):
|
|
sensors = get_Sensors(morphology)
|
|
if not sensors:
|
|
log.error("Morphology has no sensors.")
|
|
raise ValueError("Morphology has no sensors.")
|
|
return [sensors[0]]
|
|
|
|
|
|
def get_InitActuator(morphology: MorphologyType):
|
|
actuators = get_Actuators(morphology)
|
|
if not actuators:
|
|
log.error("Morphology has no actuators.")
|
|
raise ValueError("Morphology has no actuators.")
|
|
return [actuators[0]]
|
|
|
|
|
|
def get_Sensors(morphology: MorphologyType) -> List[Dict[str, Any]]:
|
|
fn = _resolve_morphology(morphology)
|
|
return fn("sensors")
|
|
|
|
|
|
def get_Actuators(morphology: MorphologyType) -> List[Dict[str, Any]]:
|
|
fn = _resolve_morphology(morphology)
|
|
return fn("actuators")
|
|
|
|
|
|
def _resolve_morphology(morphology: MorphologyType) -> Callable[[str], List[Dict[str, Any]]]:
|
|
if callable(morphology):
|
|
return morphology
|
|
|
|
if isinstance(morphology, str):
|
|
reg = {
|
|
"xor_mimic": xor_mimic,
|
|
"car_racing_features": car_racing_features
|
|
}
|
|
if morphology in reg:
|
|
return reg[morphology]
|
|
log.error(f"Unknown morphology name: {morphology}")
|
|
raise ValueError(f"Unknown morphology name: {morphology}")
|
|
|
|
try:
|
|
|
|
if hasattr(morphology, "xor_mimic") and callable(getattr(morphology, "xor_mimic")):
|
|
return getattr(morphology, "xor_mimic")
|
|
except Exception:
|
|
pass
|
|
|
|
log.error("morphology must be a callable, a module with 'xor_mimic', or a registered string key")
|
|
raise TypeError("morphology must be a callable, a module with 'xor_mimic', or a registered string key")
|
|
|
|
|
|
def xor_mimic(kind: str) -> List[Dict[str, Any]]:
|
|
if kind == "sensors":
|
|
return [
|
|
{
|
|
"name": "xor_GetInput",
|
|
"vector_length": 2,
|
|
"scape": "xor_sim"
|
|
}
|
|
]
|
|
elif kind == "actuators":
|
|
return [
|
|
{
|
|
"name": "xor_SendOutput",
|
|
"vector_length": 1,
|
|
"scape": "xor_sim"
|
|
}
|
|
]
|
|
else:
|
|
log.error(f"xor_mimic: unsupported kind '{kind}', expected 'sensors' or 'actuators'")
|
|
raise ValueError(f"xor_mimic: unsupported kind '{kind}', expected 'sensors' or 'actuators'")
|
|
|
|
|
|
def car_racing_features(kind: str) -> List[Dict[str, Any]]:
|
|
"""
|
|
car racing morphology
|
|
"""
|
|
LOOK_AHEAD = 10
|
|
feature_len = LOOK_AHEAD + 6
|
|
|
|
if kind == "sensors":
|
|
return [
|
|
{
|
|
"name": "car_GetFeatures",
|
|
"vector_length": feature_len,
|
|
"scape": "car_racing"
|
|
}
|
|
]
|
|
elif kind == "actuators":
|
|
return [
|
|
{
|
|
"name": "car_ApplyAction",
|
|
"vector_length": 3,
|
|
"scape": "car_racing"
|
|
}
|
|
]
|
|
else:
|
|
log.error(f"car_racing_features: unsupported kind '{kind}', expected 'sensors' or 'actuators'")
|
|
raise ValueError("car_racing_features: kind must be 'sensors' or 'actuators'")
|