feat(a750): initial A-750 robot support and blueprint#1911
feat(a750): initial A-750 robot support and blueprint#1911adob wants to merge 2 commits intodimensionalOS:devfrom
Conversation
Greptile SummaryThis PR adds initial support for the A-750 robotic arm: a new catalog entry, a keyboard-teleop blueprint, an LFS URDF bundle, and a bug fix that seeds
Confidence Score: 4/5Safe to merge after fixing the missing One P1 regression: the XArm7 blueprint was left with an un-fixed
Important Files Changed
Sequence DiagramsequenceDiagram
participant User as User (keyboard)
participant KTM as KeyboardTeleopModule
participant JogState as JogState.from_fk
participant Pinocchio as Pinocchio (URDF)
participant LCM as LCM Transport
participant CC as ControlCoordinator
participant A750 as A-750 Adapter
KTM->>JogState: from_fk(model_path, ee_joint_id, q_home)
JogState->>Pinocchio: buildModelFromUrdf(a750_rev1_no_gripper.urdf)
Pinocchio-->>JogState: model (nq=6)
JogState->>Pinocchio: forwardKinematics(model, data, q_init)
Pinocchio-->>JogState: EE pose (translation + rotation)
JogState-->>KTM: initial home_pose
loop Each keyboard tick
User->>KTM: keypress (WASD/arrows/QE)
KTM->>KTM: delta applied to current_pose
KTM->>LCM: publish PoseStamped /coordinator/cartesian_command
LCM->>CC: cartesian_command
CC->>CC: CartesianIK solve to joint angles
CC->>A750: send joint commands
CC->>LCM: publish JointState /coordinator/joint_state
LCM->>KTM: joint_state (feedback)
end
|
| "model_path": LfsPath("a750_description") / "urdf/a750_rev1.urdf", | ||
| "end_effector_link": "gripper_base", | ||
| "adapter_type": adapter_type, | ||
| "device_path": device_path, |
There was a problem hiding this comment.
device_path silently dropped — real hardware won't receive the port
device_path is placed in the defaults dict and passed to RobotConfig(**defaults), but RobotConfig has no device_path field — only address. Pydantic v2 silently ignores unknown fields, so the device path is discarded. When a user sets DEVICE_PATH=/dev/ttyACM0, the adapter type correctly switches to "a750", but the adapter never learns which serial port to open. The real-hardware path is broken.
Use address instead:
"address": device_path,| "device_path": device_path, | |
| "address": device_path, |
| "/coordinator/cartesian_command", PoseStamped | ||
| ), | ||
| ("joint_state", JointState): LCMTransport("/coordinator/joint_state", JointState), | ||
| ("gripper_command", float): LCMTransport("/coordinator/gripper_command", Float32), |
There was a problem hiding this comment.
gripper_command transport registered but stream doesn't exist
The blueprint registers a transport for ("gripper_command", float), but KeyboardTeleopModule declares no gripper_command: Out[float] stream. The PR description acknowledges gripper control is not yet implemented. Depending on how autoconnect/.transports() validates stream names, this could raise a KeyError or AttributeError at startup, preventing the blueprint from launching entirely.
Either remove this transport entry until the stream is implemented, or add a no-op placeholder that can be wired up safely.
| # Copyright 2026 Dimensional Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # Copyright 2025-2026 Dimensional Inc. | ||
| # Copyright 2026 Aleksandr Dobkin | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. |
Implement initial support the A-750 robotic arm.
The following additional changes were made:
Bug fix:
JogState.from_fkwas computing the initial EE pose at the all-zeros joint configuration (q = [0,0,0,0,0,0]), while the A-750 home configuration is[0, 0, -90°, 0, 0, 0]. The immediately-published target pose was unreachable from home within the 15°/tick safety limit. Fixed by adding an optionalq_homeparameter toJogState.from_fkand threadinghome_jointsfromRobotConfigthroughKeyboardTeleopConfig→KeyboardTeleopModule.The following additional changes are contemplated but not yet implemented:
Gripper control: Added
O/Ckey bindings toKeyboardTeleopModulefor open/close. The module gains agripper_command: Out[float]stream, andKeyboardTeleopConfiggainsgripper_joint,gripper_open_pos,gripper_closed_posfields. The a750 blueprint wires these fromRobotConfig.gripperand routesgripper_commandover LCM to the coordinator.CartesianIKTaskandControlCoordinatorwere extended to accept and forward gripper position commands alongside arm joint commands.Breaking Changes
None. All new fields are optional with safe defaults; existing blueprints that don't configure a gripper are unaffected.
How to Test
# Start the keyboard teleop blueprint dimos run keyboard-teleop-a750Contributor License Agreement