Skip to content

Commit 232a1ee

Browse files
authored
Merge pull request #275 from maxspahn/ft-windows-compatibility
## Summary Makes this repository easily accessible for windows users, by making pybullet an optional dependency. ## Rationale When working on windows, the installation of this repository is complicated, because it requires C++ compilers which are not installed by default on windows, see #137. By making pybullet an optional dependency, it is possible to use this repo without pybullet and rely fully on mujoco. The idea was mentioned in #264.
2 parents bd7e6a5 + cdfef89 commit 232a1ee

36 files changed

+1143
-827
lines changed

.github/workflows/create_release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
id: setup-python
2525
uses: actions/setup-python@v2
2626
with:
27-
python-version: 3.8
27+
python-version: "3.10"
2828
- name: Install poetry
2929
uses: snok/install-poetry@v1
3030
with:
@@ -72,7 +72,7 @@ jobs:
7272
- name: Publish to pypi
7373
uses: JRubics/[email protected]
7474
with:
75-
python_version: "3.8"
75+
python_version: "3.10"
7676
pypi_token: ${{ secrets.PYPI_TOKEN }}
7777
- name: Update develop branch
7878
run: |

.github/workflows/docs_pages.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
id: setup-python
1919
uses: actions/setup-python@v2
2020
with:
21-
python-version: 3.8
21+
python-version: 3.10
2222
#----------------------------------------------
2323
# ----- install & configure poetry -----
2424
#----------------------------------------------

.github/workflows/pylint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
python-version: ["3.8"]
14+
python-version: ["3.10"]
1515
steps:
1616
- uses: actions/checkout@v2
1717
- name: Set up Python ${{ matrix.python-version }}

.github/workflows/unitTest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
id: setup-python
2424
uses: actions/setup-python@v2
2525
with:
26-
python-version: 3.8
26+
python-version: "3.10"
2727
#----------------------------------------------
2828
# ----- install & configure poetry -----
2929
#----------------------------------------------
@@ -48,7 +48,7 @@ jobs:
4848
#----------------------------------------------
4949
- name: Install dependencies
5050
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
51-
run: poetry install --no-interaction --no-root --with dev --with mujoco
51+
run: poetry install --no-interaction --no-root --with dev --with mujoco --with pybullet
5252
#----------------------------------------------
5353
# install your root project, if required
5454
#----------------------------------------------

examples/mujoco_example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from robotmodels.utils.robotmodel import RobotModel, LocalRobotModel
66
from urdfenvs.generic_mujoco.generic_mujoco_env import GenericMujocoEnv
77
from urdfenvs.generic_mujoco.generic_mujoco_robot import GenericMujocoRobot
8-
from urdfenvs.sensors.free_space_decomposition import FreeSpaceDecompositionSensor
8+
from urdfenvs.sensors.mujoco.free_space_decomposition import FreeSpaceDecompositionSensorMujoco as FreeSpaceDecompositionSensor
99
from urdfenvs.sensors.free_space_occupancy import FreeSpaceOccupancySensor
1010
from urdfenvs.sensors.full_sensor import FullSensor
11-
from urdfenvs.sensors.lidar import Lidar
11+
from urdfenvs.sensors.mujoco.lidar import LidarMujoco as Lidar
1212
from urdfenvs.sensors.sdf_sensor import SDFSensor
1313
from urdfenvs.scene_examples.obstacles import sphereObst1, sphereObst2, wall_obstacles, cylinder_obstacle, dynamicSphereObst1, movable_obstacle
1414
from urdfenvs.scene_examples.goal import goal1

examples/multi_robot.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import os
2+
23
import numpy as np
34

5+
from urdfenvs.robots.generic_urdf import GenericDiffDriveRobot, GenericUrdfReacher
46
from urdfenvs.urdf_common.urdf_env import UrdfEnv
5-
from urdfenvs.robots.generic_urdf import GenericUrdfReacher
6-
from urdfenvs.robots.generic_urdf import GenericDiffDriveRobot
7+
78

89
def run_multi_robot(n_steps=1000, render=False, obstacles=False, goal=False):
910
jackal_1 = GenericDiffDriveRobot(
@@ -16,8 +17,8 @@ def run_multi_robot(n_steps=1000, render=False, obstacles=False, goal=False):
1617
"front_left_wheel",
1718
],
1819
castor_wheels=[],
19-
wheel_radius = 0.098,
20-
wheel_distance = 2 * 0.187795 + 0.08,
20+
wheel_radius=0.098,
21+
wheel_distance=2 * 0.187795 + 0.08,
2122
)
2223
jackal_2 = GenericDiffDriveRobot(
2324
urdf="jackal.urdf",
@@ -29,16 +30,16 @@ def run_multi_robot(n_steps=1000, render=False, obstacles=False, goal=False):
2930
"front_left_wheel",
3031
],
3132
castor_wheels=[],
32-
wheel_radius = 0.098,
33-
wheel_distance = 2 * 0.187795 + 0.08,
33+
wheel_radius=0.098,
34+
wheel_distance=2 * 0.187795 + 0.08,
3435
)
3536
boxer = GenericDiffDriveRobot(
3637
urdf="boxer.urdf",
3738
mode="vel",
3839
actuated_wheels=["wheel_right_joint", "wheel_left_joint"],
3940
castor_wheels=["rotacastor_right_joint", "rotacastor_left_joint"],
40-
wheel_radius = 0.08,
41-
wheel_distance = 0.494,
41+
wheel_radius=0.08,
42+
wheel_distance=0.494,
4243
)
4344
ur5_urdf_file = os.path.dirname(os.path.abspath(__file__)) + "/ur5.urdf"
4445
robots = [
@@ -49,32 +50,43 @@ def run_multi_robot(n_steps=1000, render=False, obstacles=False, goal=False):
4950
boxer,
5051
]
5152

52-
env: UrdfEnv = UrdfEnv(
53-
dt=0.01, robots=robots, render=render
54-
)
53+
env: UrdfEnv = UrdfEnv(dt=0.01, robots=robots, render=render)
5554
n = env.n()
5655
action = np.ones(n) * -0.2
5756
pos0 = np.zeros(n)
5857
pos0[1] = -0.0
5958
ns_per_robot = env.ns_per_robot()
6059
n_per_robot = env.n_per_robot()
61-
initial_positions = np.array([np.zeros(n) for n in ns_per_robot])
60+
initial_positions = [np.zeros(n) for n in ns_per_robot]
61+
max_len = max([len(arr) for arr in initial_positions])
62+
padded_initial_positions = np.array(
63+
[
64+
np.pad(
65+
arr,
66+
(0, max_len - len(arr)),
67+
mode="constant",
68+
constant_values=np.nan,
69+
)
70+
for arr in initial_positions
71+
]
72+
)
73+
6274
for i in range(len(initial_positions)):
6375
if ns_per_robot[i] != n_per_robot[i]:
64-
initial_positions[i][0:2] = np.array([0.0, i])
76+
padded_initial_positions[i][0:2] = np.array([0.0, i])
6577
mount_positions = np.array(
66-
[
67-
np.array([0.0, i, 0.0]) for i in range(len(ns_per_robot))
68-
]
78+
[np.array([0.0, i, 0.0]) for i in range(len(ns_per_robot))]
6979
)
70-
ob = env.reset(pos=initial_positions,mount_positions=mount_positions)
80+
ob = env.reset(pos=padded_initial_positions, mount_positions=mount_positions)
7181
print(f"Initial observation : {ob}")
7282
if goal:
7383
from urdfenvs.scene_examples.goal import dynamicGoal
84+
7485
env.add_goal(dynamicGoal)
7586

7687
if obstacles:
7788
from urdfenvs.scene_examples.obstacles import dynamicSphereObst2
89+
7890
env.add_obstacle(dynamicSphereObst2)
7991

8092
print("Starting episode")

examples/point_robot_free_space_decomp.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import gymnasium as gym
21
import pprint
2+
3+
import gymnasium as gym
34
import numpy as np
4-
from urdfenvs.scene_examples.obstacles import (
5-
sphereObst1,
6-
sphereObst2,
7-
urdfObst1,
8-
dynamicSphereObst3,
9-
dynamicSphereObst1,
10-
wall_obstacles,
11-
)
125

136
from urdfenvs.robots.generic_urdf import GenericUrdfReacher
14-
from urdfenvs.sensors.free_space_decomposition import FreeSpaceDecompositionSensor
7+
from urdfenvs.scene_examples.obstacles import (dynamicSphereObst1,
8+
dynamicSphereObst3, sphereObst1,
9+
sphereObst2, urdfObst1,
10+
wall_obstacles)
11+
from urdfenvs.sensors.pybullet.free_space_decomposition import \
12+
FreeSpaceDecompositionSensorPybullet as FreeSpaceDecompositionSensor
1513
from urdfenvs.urdf_common.urdf_env import UrdfEnv
1614

1715

examples/point_robot_occupancy_sensor.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
11
import gymnasium as gym
22
import numpy as np
33

4-
from urdfenvs.urdf_common.urdf_env import UrdfEnv
54
from urdfenvs.robots.generic_urdf import GenericUrdfReacher
6-
from urdfenvs.sensors.occupancy_sensor import OccupancySensor
75
from urdfenvs.scene_examples.obstacles import (
86
cylinder_obstacle,
9-
sphereObst2,
10-
sphereObst1,
117
dynamicSphereObst1,
8+
sphereObst1,
9+
sphereObst2,
10+
)
11+
from urdfenvs.sensors.pybullet.occupancy_sensor import (
12+
OccupancySensorPybullet as OccupancySensor,
1213
)
14+
from urdfenvs.urdf_common.urdf_env import UrdfEnv
1315

1416

1517
def get_index_from_coordinates(point, mesh) -> tuple:
1618
distances = np.linalg.norm(mesh - point, axis=3)
1719
return np.unravel_index(np.argmin(distances), mesh.shape[:-1])
1820

21+
1922
def evaluate_occupancy(point, mesh, occupancy, resolution) -> int:
2023
index = list(get_index_from_coordinates(point, mesh))
2124
return occupancy[tuple(index)]
2225

2326

24-
25-
26-
def run_point_robot_with_occupancy_sensor(n_steps=10, render=False, obstacles=True, goal=True):
27+
def run_point_robot_with_occupancy_sensor(
28+
n_steps=10, render=False, obstacles=True, goal=True
29+
):
2730
robots = [
2831
GenericUrdfReacher(urdf="pointRobot.urdf", mode="vel"),
2932
]
30-
env: UrdfEnv = UrdfEnv(
31-
dt=0.01, robots=robots, render=render
32-
)
33+
env: UrdfEnv = UrdfEnv(dt=0.01, robots=robots, render=render)
3334
env.add_obstacle(sphereObst2)
3435
env.add_obstacle(cylinder_obstacle)
3536
env.add_obstacle(sphereObst1)
@@ -38,8 +39,8 @@ def run_point_robot_with_occupancy_sensor(n_steps=10, render=False, obstacles=Tr
3839
# add sensor
3940
val = 40
4041
sensor = OccupancySensor(
41-
limits = np.array([[-5, 5], [-5, 5], [0, 50/val]]),
42-
resolution = np.array([val + 1, val + 1, 5], dtype=int),
42+
limits=np.array([[-5, 5], [-5, 5], [0, 50 / val]]),
43+
resolution=np.array([val + 1, val + 1, 5], dtype=int),
4344
interval=100,
4445
plotting_interval=100,
4546
)
@@ -64,9 +65,11 @@ def run_point_robot_with_occupancy_sensor(n_steps=10, render=False, obstacles=Tr
6465
for _ in range(n_steps):
6566
action = defaultAction
6667
ob, *_ = env.step(action)
67-
point = np.append(ob['robot_0']['joint_state']['position'][0:2], 0.0)
68-
occupancy = ob['robot_0']['Occupancy']
69-
occupancy_eval = evaluate_occupancy(point, sensor.mesh(), occupancy, [0.2, 0.2, 1])
68+
point = np.append(ob["robot_0"]["joint_state"]["position"][0:2], 0.0)
69+
occupancy = ob["robot_0"]["Occupancy"]
70+
occupancy_eval = evaluate_occupancy(
71+
point, sensor.mesh(), occupancy, [0.2, 0.2, 1]
72+
)
7073
print(occupancy_eval)
7174
history.append(ob)
7275
env.close()

0 commit comments

Comments
 (0)