Source code for linkforge.blender.properties.control_props

"""Blender Property Groups for centralized ros2_control configuration.

These properties are stored on the Scene and define the mapping between
robot joints and ros2_control interfaces (command and state).
"""

from __future__ import annotations

import bpy
from bpy.props import (
    BoolProperty,
    CollectionProperty,
    EnumProperty,
    StringProperty,
)
from bpy.types import PropertyGroup
from linkforge.core.constants import (
    HW_IF_EFFORT,
    HW_IF_POSITION,
    HW_IF_VELOCITY,
)


[docs] class Ros2ControlParameterProperty(PropertyGroup): """Key-value pair for ros2_control parameters.""" name: StringProperty( # type: ignore name="Key", description="Parameter name", default="param", ) value: StringProperty( # type: ignore name="Value", description="Parameter value", default="0.0", )
[docs] class Ros2ControlInterfaceProperty(PropertyGroup): """Property group for a single ros2_control interface.""" name: EnumProperty( # type: ignore name="Interface", description="Interface type", items=[ (HW_IF_POSITION, "Position", "Position interface"), (HW_IF_VELOCITY, "Velocity", "Velocity interface"), (HW_IF_EFFORT, "Effort", "Effort/Torque interface"), ], default=HW_IF_POSITION, ) # Parameters for this specific interface (e.g., min/max for command interfaces) parameters: CollectionProperty(type=Ros2ControlParameterProperty) # type: ignore
[docs] class Ros2ControlJointProperty(PropertyGroup): """Property group for a joint's ros2_control mapping.""" name: StringProperty( # type: ignore name="Joint Name", description="Name of the joint in the kinematic tree", default="", ) joint_obj: bpy.props.PointerProperty( # type: ignore name="Joint Object", type=bpy.types.Object, description="Reference to the physical joint object", ) # Command Interfaces (what we send) # Using Booleans for common interfaces for quick UI access cmd_position: BoolProperty(name="Position", default=True) # type: ignore cmd_velocity: BoolProperty(name="Velocity", default=False) # type: ignore cmd_effort: BoolProperty(name="Effort", default=False) # type: ignore # State Interfaces (what we read) state_position: BoolProperty(name="Position", default=True) # type: ignore state_velocity: BoolProperty(name="Velocity", default=True) # type: ignore state_effort: BoolProperty(name="Effort", default=False) # type: ignore # UI State show_parameters: BoolProperty(name="Show Parameters", default=False) # type: ignore # Advanced parameters (rarely used but supported by spec) parameters: CollectionProperty(type=Ros2ControlParameterProperty) # type: ignore
[docs] def register() -> None: """Register property groups.""" for cls in [ Ros2ControlParameterProperty, Ros2ControlInterfaceProperty, Ros2ControlJointProperty, ]: try: bpy.utils.register_class(cls) except ValueError: bpy.utils.unregister_class(cls) bpy.utils.register_class(cls)
[docs] def unregister() -> None: """Unregister property groups.""" bpy.utils.unregister_class(Ros2ControlJointProperty) bpy.utils.unregister_class(Ros2ControlInterfaceProperty) bpy.utils.unregister_class(Ros2ControlParameterProperty)
if __name__ == "__main__": register()