Skip to content

Commit 180681b

Browse files
committed
Updates robot base frame and tool configurations in setting robot cell state
This facilitates more accurate simulation of robot cell states, particularly when dealing with tools that have configurable joints.
1 parent 46f5c8d commit 180681b

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

src/compas_fab/backends/pybullet/backend_features/pybullet_set_robot_cell_state.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def set_robot_cell_state(self, robot_cell_state: RobotCellState):
7171
# Note robot_cell_state.robot_configuration is a full configuration
7272
if robot_cell_state.robot_configuration:
7373
client._set_robot_configuration(robot_cell_state.robot_configuration)
74+
client._set_base_frame(robot_cell_state.robot_base_frame, client.robot_puid)
7475

7576
# Keep track of tool's base_frames during tool updates
7677
# They can be used later to update rigid body base frames that are attached to tools
@@ -105,6 +106,8 @@ def set_robot_cell_state(self, robot_cell_state: RobotCellState):
105106

106107
# Set the frame of the tool
107108
client._set_tool_base_frame(tool_name, tool_base_frame)
109+
if tool_state.configuration:
110+
client._set_tool_configuration(tool_name, tool_state.configuration)
108111

109112
# Update the position of RigidBody models
110113
for rigid_body_name, rigid_body_state in robot_cell_state.rigid_body_states.items():

src/compas_fab/backends/pybullet/client.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,13 @@ def _get_link_name(self, link_id, body_id):
672672
return self._get_base_name(body_id)
673673
return self._get_joint_info(link_id, body_id).linkName.decode("UTF-8")
674674

675+
def _get_joint_id_from_name(self, body_id, joint_name):
676+
for joint_id in list(range(self._get_num_joints(body_id))):
677+
parsed_jt_name = self._get_joint_name(joint_id, body_id)
678+
if parsed_jt_name == joint_name:
679+
return joint_id
680+
raise ValueError(body_id, joint_name)
681+
675682
# ----------------------------------------
676683
# Functions for configuration and frames
677684
# ----------------------------------------
@@ -743,6 +750,55 @@ def _set_robot_configuration(self, configuration: Configuration):
743750
# Note: If the joint that is being mimicked is not in the configuration, the mimic joint will not be set.
744751
# This search and replace can be more elaborate in the future if needed.
745752

753+
def _set_tool_configuration(self, tool_name: str, configuration: Configuration):
754+
"""Sets the tool's pose to the given configuration.
755+
756+
Only the joint values in the configuration are set.
757+
The other joint values are not changed.
758+
759+
Parameters
760+
----------
761+
tool_name : :obj:`str`
762+
Name of the tool to be configured.
763+
configuration : :class:`compas_fab.robots.Configuration`
764+
The configuration to be set, ``joint_names`` must be included in the configuration.
765+
766+
"""
767+
# Check if the tool has been loaded
768+
assert (
769+
tool_name in self.tools_puids
770+
), f"Tool '{tool_name}' must be loaded before setting configuration."
771+
772+
tool_id = self.tools_puids[tool_name]
773+
774+
if configuration is None or configuration.joint_names == []:
775+
return
776+
777+
# Get the PyBullet body unique id for the tool
778+
tool_uid = self.tools_puids[tool_name]
779+
780+
# Iterate through all joints that are considered free by PyBullet for this tool
781+
for joint_name in configuration.joint_names:
782+
joint_puid = self._get_joint_id_from_name(tool_uid, joint_name)
783+
if joint_name in configuration:
784+
self._set_joint_position(joint_puid, configuration[joint_name], tool_id)
785+
else:
786+
pass
787+
# TODO: Add support for mimic joints
788+
# # Check if this is mimic joint
789+
# tool_model = self.robot_cell.tool_models[tool_name]
790+
# joint = tool_model.get_joint_by_name(joint_name)
791+
# mimic: Mimic = joint.mimic
792+
# # Get the value of the joint that is being mimicked (works only for non-cascaded mimic)
793+
# if mimic:
794+
# if mimic.joint in configuration:
795+
# mimicked_joint_position = configuration[mimic.joint]
796+
# self._set_joint_position(
797+
# joint_puid, mimic.calculate_position(mimicked_joint_position), tool_id
798+
# )
799+
# # Note: If the joint that is being mimicked is not in the configuration, the mimic joint will not be set.
800+
# # This search and replace can be more elaborate in the future if needed.
801+
746802
def _get_robot_configuration(self) -> Configuration:
747803
"""Gets the robot's current pose.
748804
A full configuration is returned.

0 commit comments

Comments
 (0)