DaMiaoController¶
damiao_motor.core.controller.DaMiaoController ¶
DaMiaoController(channel: str = 'can0', bustype: str = 'socketcan', bitrate: Optional[int] = None, **kwargs: Any)
Simple multi-motor controller.
- Owns a single CAN bus.
- Manages multiple DaMiaoMotor instances on that bus.
- Automatically polls feedback in background when motors are present.
- Provides helper methods to:
- enable/disable all motors
- send commands to one or all motors
- poll feedback non-blockingly
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel |
str
|
For |
'can0'
|
bustype |
str
|
python-can interface name ( |
'socketcan'
|
bitrate |
Optional[int]
|
CAN bitrate in bits/s. Required for |
None
|
**kwargs |
Any
|
Extra arguments forwarded to |
{}
|
Source code in damiao_motor/core/controller.py
add_motor ¶
Create and register a motor on this controller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
motor_id |
int
|
Command CAN ID (ESC_ID) used to send commands to the motor. |
required |
feedback_id |
int
|
Feedback CAN ID (MST_ID) configured on the motor. |
required |
motor_type |
str
|
Motor type preset name (for example |
required |
**kwargs |
Any
|
Extra arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
DaMiaoMotor
|
The created |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a motor with the same |
Source code in damiao_motor/core/controller.py
all_motors ¶
Iterate over all registered motors.
Returns:
| Type | Description |
|---|---|
Iterable[DaMiaoMotor]
|
Iterable of |
disable_all ¶
enable_all ¶
flush_bus ¶
Flush all pending messages from the CAN bus buffer.
Returns:
| Type | Description |
|---|---|
int
|
Number of messages flushed. |
Raises:
| Type | Description |
|---|---|
CanOperationError
|
If CAN interface is down (Error Code 100) with helpful hint |
OSError
|
If other network/system errors occur |
Source code in damiao_motor/core/controller.py
get_motor ¶
Get a registered motor by command ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
motor_id |
int
|
Command CAN ID (ESC_ID) used when the motor was added. |
required |
Returns:
| Type | Description |
|---|---|
DaMiaoMotor
|
The matching |
Source code in damiao_motor/core/controller.py
poll_feedback ¶
Drain pending CAN frames (non-blocking) and dispatch feedback to motors.
Behavior:
- Uses self.bus.recv(timeout=0) in a loop to read all currently queued
frames without blocking.
- Stops the loop when recv returns None (queue is empty).
- Ignores frames that are not 8 bytes.
- Routes frames by logical motor ID encoded in the low 4 bits of D[0].
- For matched motors, forwards frames to
DaMiaoMotor.process_feedback_frame(...).
Notes: - This method performs one drain pass. It can be called manually, and is also used repeatedly by the background polling thread. - If bus/controller state becomes invalid (for example bus closed), polling is marked inactive to let background loop exit cleanly.
Source code in damiao_motor/core/controller.py
send_cmd ¶
send_cmd(motor_id: int, target_position: float = 0.0, target_velocity: float = 0.0, stiffness: float = 0.0, damping: float = 0.0, feedforward_torque: float = 0.0) -> None
Send MIT mode command to a specific motor (convenience method).
Source code in damiao_motor/core/controller.py
send_cmd_all ¶
send_cmd_all(target_position: float = 0.0, target_velocity: float = 0.0, stiffness: float = 0.0, damping: float = 0.0, feedforward_torque: float = 0.0) -> None
Send MIT mode command to all motors (convenience method).
Source code in damiao_motor/core/controller.py
shutdown ¶
Shutdown controller resources in a safe order.
Steps:
1. Stop background polling thread (via _stop_polling).
2. Disable all registered motors.
3. Shutdown the CAN bus handle.
This ensures polling is not racing against bus shutdown.