Coverage for src/pyroboplan/models/panda.py: 98%
46 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-02 21:56 -0500
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-02 21:56 -0500
1"""Utilities to load example Franka Emika Panda model."""
3import coal
4import numpy as np
5import os
6import pinocchio
8from ..core.utils import set_collisions
9from .utils import get_example_models_folder
12def load_models(use_sphere_collisions=False):
13 """
14 Gets the example Panda models.
16 Returns
17 -------
18 tuple[`pinocchio.Model`]
19 A 3-tuple containing the model, collision geometry model, and visual geometry model.
20 """
21 models_folder = get_example_models_folder()
22 package_dir = os.path.join(models_folder, "panda_description")
23 urdf_filename = "panda_spheres.urdf" if use_sphere_collisions else "panda.urdf"
24 urdf_filepath = os.path.join(package_dir, "urdf", urdf_filename)
26 return pinocchio.buildModelsFromUrdf(urdf_filepath, package_dirs=models_folder)
29def add_self_collisions(model, collision_model, srdf_filename=None):
30 """
31 Adds link self-collisions to the Panda collision model.
33 This uses an SRDF file to remove any excluded collision pairs.
35 Parameters
36 ----------
37 model : `pinocchio.Model`
38 The Panda model.
39 collision_model : `pinocchio.Model`
40 The Panda collision geometry model.
41 srdf_filename : str, optional
42 Path to the SRDF file describing the excluded collision pairs.
43 If not specified, uses a default file included with the Panda model.
44 """
45 if srdf_filename is None: 45 ↛ 50line 45 didn't jump to line 50 because the condition on line 45 was always true
46 models_folder = get_example_models_folder()
47 package_dir = os.path.join(models_folder, "panda_description")
48 srdf_filename = os.path.join(package_dir, "srdf", "panda.srdf")
50 collision_model.addAllCollisionPairs()
51 pinocchio.removeCollisionPairs(model, collision_model, srdf_filename)
54def add_object_collisions(model, collision_model, visual_model, inflation_radius=0.0):
55 """
56 Adds obstacles and collisions to the Panda collision model.
58 Parameters
59 ----------
60 model : `pinocchio.Model`
61 The Panda model.
62 collision_model : `pinocchio.Model`
63 The Panda collision geometry model.
64 visual_model : `pinocchio.Model`
65 The Panda visual geometry model.
66 inflation_radius : float, optional
67 An inflation radius, in meters, around the objects.
68 """
69 # Add the collision objects
70 ground_plane = pinocchio.GeometryObject(
71 "ground_plane",
72 0,
73 pinocchio.SE3(np.eye(3), np.array([0.0, 0.0, -0.151])),
74 coal.Box(2.0, 2.0, 0.3),
75 )
76 ground_plane.meshColor = np.array([0.5, 0.5, 0.5, 0.5])
77 visual_model.addGeometryObject(ground_plane)
78 collision_model.addGeometryObject(ground_plane)
80 obstacle_sphere_1 = pinocchio.GeometryObject(
81 "obstacle_sphere_1",
82 0,
83 pinocchio.SE3(np.eye(3), np.array([0.0, 0.1, 1.1])),
84 coal.Sphere(0.2 + inflation_radius),
85 )
86 obstacle_sphere_1.meshColor = np.array([0.0, 1.0, 0.0, 0.5])
87 visual_model.addGeometryObject(obstacle_sphere_1)
88 collision_model.addGeometryObject(obstacle_sphere_1)
90 obstacle_sphere_2 = pinocchio.GeometryObject(
91 "obstacle_sphere_2",
92 0,
93 pinocchio.SE3(np.eye(3), np.array([0.5, 0.5, 0.5])),
94 coal.Sphere(0.25 + inflation_radius),
95 )
96 obstacle_sphere_2.meshColor = np.array([1.0, 1.0, 0.0, 0.5])
97 visual_model.addGeometryObject(obstacle_sphere_2)
98 collision_model.addGeometryObject(obstacle_sphere_2)
100 obstacle_box_1 = pinocchio.GeometryObject(
101 "obstacle_box_1",
102 0,
103 pinocchio.SE3(np.eye(3), np.array([-0.5, 0.5, 0.7])),
104 coal.Box(
105 0.25 + 2.0 * inflation_radius,
106 0.55 + 2.0 * inflation_radius,
107 0.55 + 2.0 * inflation_radius,
108 ),
109 )
110 obstacle_box_1.meshColor = np.array([1.0, 0.0, 0.0, 0.5])
111 visual_model.addGeometryObject(obstacle_box_1)
112 collision_model.addGeometryObject(obstacle_box_1)
114 obstacle_box_2 = pinocchio.GeometryObject(
115 "obstacle_box_2",
116 0,
117 pinocchio.SE3(np.eye(3), np.array([-0.5, -0.5, 0.75])),
118 coal.Box(
119 0.33 + 2.0 * inflation_radius,
120 0.33 + 2.0 * inflation_radius,
121 0.33 + 2.0 * inflation_radius,
122 ),
123 )
124 obstacle_box_2.meshColor = np.array([0.0, 0.0, 1.0, 0.5])
125 visual_model.addGeometryObject(obstacle_box_2)
126 collision_model.addGeometryObject(obstacle_box_2)
128 # Define the active collision pairs between the robot and obstacle links.
129 collision_names = [
130 cobj.name for cobj in collision_model.geometryObjects if "panda" in cobj.name
131 ]
132 obstacle_names = [
133 "ground_plane",
134 "obstacle_box_1",
135 "obstacle_box_2",
136 "obstacle_sphere_1",
137 "obstacle_sphere_2",
138 ]
139 for obstacle_name in obstacle_names:
140 for collision_name in collision_names:
141 set_collisions(model, collision_model, obstacle_name, collision_name, True)
143 # Exclude the collision between the ground and the base link
144 set_collisions(model, collision_model, "panda_link0", "ground_plane", False)