Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for PyBulletClient and PyBulletPlanner #429

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
bb1bd4d
add tool_coordinate_frame stub
yck011522 May 3, 2024
7926032
Add tool_coordinate_frame parameter to Waypoints constructor
yck011522 May 3, 2024
a49f023
Refactor plan_cartesian_motion method in Robot class
yck011522 May 3, 2024
c0f92d7
Refactor plan_cartesian_motion method to accept waypoints instead of …
yck011522 May 3, 2024
1d6c96b
Refactor plan_cartesian_motion method to accept waypoints and impleme…
yck011522 May 9, 2024
63b89fb
I bit more comments
yck011522 May 9, 2024
b56b144
ros backend plan_cartesian_motion uses waypoints
yck011522 May 10, 2024
5d10999
comment change
yck011522 May 10, 2024
1fcadb5
add type check, fix some mistakes
yck011522 May 10, 2024
1c23183
Fix bugs in Targets
yck011522 May 10, 2024
eb856ec
test file
yck011522 May 10, 2024
9eb80fb
changed 3 doc tests files
yck011522 May 10, 2024
23acbf9
docs and change log
yck011522 May 10, 2024
02f9753
fix IPY type checking
yck011522 May 10, 2024
49847ed
more stuff
yck011522 May 10, 2024
a4f697f
Change planning backend features to use inherence instead of call for…
yck011522 May 10, 2024
c5b4748
changelog
yck011522 May 10, 2024
ff98cb0
Better generated docs
yck011522 May 10, 2024
f1064ce
render compas_fab.backends.ros.backend_features in docs
yck011522 May 10, 2024
5bfe447
unbreak my heart
yck011522 May 10, 2024
7d15d94
Renamed `get_cached_robot` to `get_cached_robot_model`
yck011522 May 29, 2024
41c08d7
Found error in PyBullet _accurate_inverse_kinematics when comparing t…
yck011522 May 30, 2024
e82b723
Fixed error in PyBulletForwardKinematics.forward_kinematics where fun…
yck011522 May 30, 2024
4ed1f6c
Added `PyBulletClient.load_existing_robot`
yck011522 May 30, 2024
03d0a16
Added notes in docstring of `get_link_names_with_collision_geometry`
yck011522 May 30, 2024
4f83af7
Added unit test for `PyBulletClient` and `PyBulletPlanner`
yck011522 May 30, 2024
c1dff0a
Update docs/examples/02_description_models/03_targets.rst
yck011522 May 31, 2024
13bd652
Remove type hints from new files
yck011522 Jun 6, 2024
de28b22
Rephrased the developer note inside _plan_cartesian_motion_with_frame…
yck011522 Jun 6, 2024
e7dc608
Rephrased the doc for `waypoint` parameter in `robot.plan_cartesian_m…
yck011522 Jun 6, 2024
34f60be
Fixed incorrect docs for target and waypoint
yck011522 Jun 6, 2024
a01221b
chore: Refactor tolerance_orientation calculation in FrameTarget
yck011522 Jun 6, 2024
88c1ee2
lint
yck011522 Jun 6, 2024
93b7502
Merge branch 'feature_plan_c_motion_uses_waypoints' into remove_plann…
yck011522 Jun 6, 2024
103d9b7
Remove pybullet client test with GUI
yck011522 Jun 6, 2024
847142a
Update CHANGELOG.md
yck011522 Jun 7, 2024
3f77062
Apply suggestions from code review
yck011522 Jun 7, 2024
90d07c4
fix test_target incorrect test at tolerance_orientation
yck011522 Jun 6, 2024
b8dd26e
Merge branch 'main' into feature_plan_c_motion_uses_waypoints
yck011522 Jun 7, 2024
e652a7f
Clean up code in plan_cartesian_motion
yck011522 Jun 12, 2024
ba32b90
Added comment about interpolation in the test for AnalyticalPyBulletC…
yck011522 Jun 12, 2024
514d2e9
Changed the default inverse kinematic high_accuracy threshold to 0.1m…
yck011522 Jun 13, 2024
c0bf89f
lint
yck011522 Jun 13, 2024
c975804
Lets see what happens if we also import PyBullet stuff in IPY environ…
yck011522 Jun 13, 2024
9c62178
Improve angle comparison at PyBullet Planner Test
yck011522 Jun 13, 2024
ee08aee
Better error message
yck011522 Jun 13, 2024
3db9aa7
Exclude PyBullet tests in Iron Python environment
yck011522 Jun 13, 2024
20d947f
Put the IPY guard back in backends import
yck011522 Jun 13, 2024
c63a5f3
Merge branch 'feature_plan_c_motion_uses_waypoints' into remove_plann…
yck011522 Jun 13, 2024
c433476
Merge branch 'remove_planner_call_magic' into tests_pybullet_client_a…
yck011522 Jun 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Added unit test for `PyBulletClient` and `PyBulletPlanner` backend features, including Ik and FK agreement tests.
* Added `PyBulletClient.load_existing_robot` to load from an existing Robot, such as those in RobotLibrary.
* Added `compas_fab.robots.Waypoints` class to represent a sequence of targets. It has two child classes: `FrameWaypoints` and `PointAxisWaypoints`.
* Added `compas_fab.robots.Target` class to represent a motion planning target.
* Added also child classes `FrameTarget`, `PointAxisTarget`, `ConfigurationTarget`, `ConstraintSetTarget`
Expand All @@ -17,6 +19,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

* Fixed error in `PyBulletForwardKinematics.forward_kinematics` where function would crash if `options` was not passed.
* Fixed error in `PyBulletInverseKinematics._accurate_inverse_kinematics` where threshold was not squared for comparison.
* Renamed `PybulletClient.get_cached_robot` to `PybulletClient.get_cached_robot_model` to avoid confusion between the `RobotModel` and `Robot` class.
* Renamed `PybulletClient.ensure_cached_robot` to `PybulletClient.ensure_cached_robot_model`.
* Renamed `PybulletClient.ensure_cached_robot_geometry` to `PybulletClient.ensure_cached_robot_model_geometry`.
* Renamed `PybulletClient.cache_robot` to `PybulletClient.cache_robot_model`.
* Backend planners now use multi-inherence instead of `__call__` to include the backend functions. This allows for better generated documentation.
* `Robot.plan_cartesian_motion()` now accepts `Waypoints` as target. Implementation for `FrameWaypoints` is supported with same functionality as before. Simply wrap `Frame` objects using `FrameWaypoints(frames)`.
* Changed `BoundingVolume`, `Constraint`, `JointConstraint`, `OrientationConstraint`, `PositionConstraint` to inherit from `compas.data.Data` class.
* Change the signature of `plan_motion()` to use `target` (`Target` class) instead of `goal_constraints`. Only one target is accepted. Users who wish to compose their own constraint sets can still use `ConstraintSetTarget`.
* Moved `Robot.orientation_constraint_from_frame()` to `OrientationConstraint.from_frame()`, as constraints are no longer intended for users to use directly.
Expand Down
12 changes: 12 additions & 0 deletions docs/developer/backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,15 @@ Backend interfaces
==================

.. automodule:: compas_fab.backends.interfaces

Implemented backend features
============================

The following backend features are implemented for the ROS backend:

.. automodule:: compas_fab.backends.ros.backend_features

The following backend features are implemented for the PyBullet backend:

.. automodule:: compas_fab.backends.pybullet.backend_features

33 changes: 29 additions & 4 deletions docs/examples/02_description_models/03_targets.rst
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
.. _targets:

*******************************************************************************
Targets
Targets and Waypoints
*******************************************************************************

-----------------------
Single Targets (Static)
Targets (Single Goal)
-----------------------

Target classes are used to describe the goal condition (i.e. end condition) of a robot
for motion planning. They can be used for both Free Motion Planning (FMP) and Cartesian
Motion Planning (CMP).
for motion planning. They can be used for Free-space Motion Planning with :meth:`compas_fab.robots.Robot.plan_motion`.

The :class:`compas_fab.robots.FrameTarget` is the most common target for motion planning.
It defines the complete pose of the end-effector (or the robot flange, if no tool is attached).
Expand Down Expand Up @@ -38,3 +37,29 @@ The :class:`compas_fab.robots.ConstraintSetTarget` class is used to specify a li
constraints as a planning target. This is intended for advanced users who want to create custom
combination of constraints. See :class:`compas_fab.robots.Constraint` for available
constraints. At the moment, only the ROS MoveIt planning backend supports this target type.

.. _waypoints:

------------------------------------------
Waypoints (Multiple Points / Segments)
------------------------------------------

Waypoints classes are used to describe a sequence of
waypoints that the robot should pass through in a planned motion. They are similar to Targets classes
but contain a list of targets instead of a single target, which is useful for tasks such as
drawing, welding or 3D printing.
They can be used for Cartesian Motion Planning with :meth:`compas_fab.robots.Robot.plan_cartesian_motion`.

The :class:`compas_fab.robots.FrameWaypoints` is the most common waypoint for Cartesian motion planning.
It defines a list of complete pose for the end-effector (or the robot flange, if no tool is attached).
It is created by a list of :class:`compas.geometry.Frame` objects or alternatively from a list of
:class:`compas.geometry.Transformation` objects.

The :class:`compas_fab.robots.PointAxisWaypoints` class is used for specifying a list of waypoints based on
the Point-Axis concept used in the :class:`compas_fab.robots.PointAxisTarget`. Compared to
:class:`~compas_fab.robots.FrameWaypoints`, this class allows for specifying targets where the rotation
around the Z-axis is not fixed. This is useful for example when the robot is using a cylindrical tool
to perform a task, for example 3D printing, welding or drilling. The freely rotating axis is defined relative
to the Z-axis of the tool coordinate frame (TCF). Note that the orientation of the tool
at the end of the motion is not determined until after the motion is planned.

12 changes: 6 additions & 6 deletions docs/examples/03_backends_ros/files/04_plan_cartesian_motion.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
from compas.geometry import Frame

from compas_fab.backends import RosClient
from compas_fab.robots import FrameWaypoints

with RosClient() as client:
robot = client.load_robot()
assert robot.name == 'ur5_robot'
assert robot.name == "ur5_robot"

frames = []
frames.append(Frame([0.3, 0.1, 0.5], [1, 0, 0], [0, 1, 0]))
frames.append(Frame([0.5, 0.1, 0.6], [1, 0, 0], [0, 1, 0]))
waypoints = FrameWaypoints(frames)

start_configuration = robot.zero_configuration()
start_configuration.joint_values = (-0.042, 0.033, -2.174, 5.282, -1.528, 0.000)
options = {
'max_step': 0.01,
'avoid_collisions': True,
"max_step": 0.01,
"avoid_collisions": True,
}

trajectory = robot.plan_cartesian_motion(frames,
start_configuration,
options=options)
trajectory = robot.plan_cartesian_motion(waypoints, start_configuration, options=options)

print("Computed cartesian path with %d configurations, " % len(trajectory.points))
print("following %d%% of requested trajectory." % (trajectory.fraction * 100))
Expand Down
17 changes: 9 additions & 8 deletions docs/examples/03_backends_ros/files/gh_plan_cartesian_motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
:class:`compas_fab.robots.JointTrajectory`
The calculated trajectory.
"""

from __future__ import print_function
import scriptcontext as sc

from compas.geometry import Frame

from compas_fab.robots import FrameWaypoints

guid = str(ghenv.Component.InstanceGuid)
response_key = "response_" + guid
Expand All @@ -38,14 +39,14 @@
if robot and robot.client and start_configuration and compute:
if robot.client.is_connected:
options = {
'max_step': float(max_step),
'avoid_collisions': bool(avoid_collisions),
'attached_collision_meshes': list(attached_colllision_meshes),
"max_step": float(max_step),
"avoid_collisions": bool(avoid_collisions),
"attached_collision_meshes": list(attached_colllision_meshes),
}
sc.sticky[response_key] = robot.plan_cartesian_motion(frames,
start_configuration=start_configuration,
group=group,
options=options)
waypoints = FrameWaypoints(frames)
sc.sticky[response_key] = robot.plan_cartesian_motion(
waypoints, start_configuration=start_configuration, group=group, options=options
)
else:
print("Robot client is not connected")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from compas.geometry import Frame

from compas_fab.backends import AnalyticalPyBulletClient
from compas_fab.robots import FrameWaypoints

frames_WCF = [
Frame((0.407, 0.073, 0.320), (0.922, 0.000, 0.388), (0.113, 0.956, -0.269)),
Expand All @@ -16,7 +17,8 @@

options = {"solver": "ur5", "check_collision": True}
start_configuration = list(robot.iter_inverse_kinematics(frames_WCF[0], options=options))[-1]
trajectory = robot.plan_cartesian_motion(frames_WCF, start_configuration=start_configuration, options=options)
waypoints = FrameWaypoints(frames_WCF)
trajectory = robot.plan_cartesian_motion(waypoints, start_configuration=start_configuration, options=options)
assert trajectory.fraction == 1.0

j = [c.joint_values for c in trajectory.points]
Expand Down
1 change: 1 addition & 0 deletions src/compas_fab/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
)

if not compas.IPY:
# PyBullet do not work in IronPython
from .pybullet import (
PyBulletClient,
CollisionError,
Expand Down
17 changes: 10 additions & 7 deletions src/compas_fab/backends/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
:toctree: generated/
:nosignatures:

BackendFeature
ForwardKinematics
InverseKinematics
PlanMotion
Expand All @@ -46,6 +47,7 @@
from .backend_features import AddAttachedCollisionMesh
from .backend_features import AddCollisionMesh
from .backend_features import AppendCollisionMesh
from .backend_features import BackendFeature
from .backend_features import ForwardKinematics
from .backend_features import GetPlanningScene
from .backend_features import InverseKinematics
Expand All @@ -58,17 +60,18 @@
from .client import PlannerInterface

__all__ = [
"AddAttachedCollisionMesh",
"AddCollisionMesh",
"AppendCollisionMesh",
"BackendFeature",
"ClientInterface",
"ForwardKinematics",
"GetPlanningScene",
"InverseKinematics",
"PlanMotion",
"PlanCartesianMotion",
"GetPlanningScene",
"AddCollisionMesh",
"AppendCollisionMesh",
"PlanMotion",
"PlannerInterface",
"RemoveCollisionMesh",
"AddAttachedCollisionMesh",
"RemoveAttachedCollisionMesh",
"ResetPlanningScene",
"ClientInterface",
"PlannerInterface",
]
Loading
Loading