Skip to content

Commit 43d3df0

Browse files
Merge pull request #908 from AVSLab/feature/625-mujoco
Adds mujoco-based Dynamics as a beta feature.
2 parents aad5265 + 6515cca commit 43d3df0

104 files changed

Lines changed: 21129 additions & 42 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pull-request.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ jobs:
8585
run: python3 -m venv .venv
8686
- name: "Install requirements_dev.txt"
8787
run: source .venv/bin/activate && pip3 install -r requirements_dev.txt pytest-error-for-skips
88+
- name: "Update 'default' conan profile to allow installing system packages"
89+
run: |
90+
source .venv/bin/activate
91+
python3 -m conans.conan profile detect --exist-ok
92+
echo -e "\n[conf]\ntools.system.package_manager:mode=install\ntools.system.package_manager:sudo=True\n" >> $(python3 -m conans.conan profile path default)
8893
- name: "Build basilisk"
8994
run: source .venv/bin/activate && python3 conanfile.py --opNav True --mujoco True --mujocoReplay True
9095

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ externalTools/fswAuto/autowrapper/wraps/*
4242
**/outputFiles/*
4343
src/moduleTemplates/autoCModule/*
4444
src/moduleTemplates/autoCppModule/*
45-
src/CMakeUserPresets.json
45+
CMakeUserPresets.json
4646

4747
supportData/EphemerisData/*.bsp
4848

conanfile.py

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import argparse
22
import os
33
import platform
4+
import json
45
import shutil
56
import subprocess
67
import sys
78
from datetime import datetime
9+
from typing import Optional, Callable
810

911
import importlib.metadata
1012
from packaging.requirements import Requirement
@@ -201,6 +203,9 @@ def requirements(self):
201203
self.requires("protobuf/3.21.12") # For compatibility with openCV
202204
self.requires("cppzmq/4.5.0")
203205

206+
if self.options.get_safe("mujoco"):
207+
self.requires(f"mujoco/{get_mujoco_version()}")
208+
204209
def configure(self):
205210
if self.options.get_safe("clean"):
206211
# clean the distribution folder to start fresh
@@ -354,13 +359,48 @@ def add_basilisk_to_sys_path(self):
354359
if err.decode() != "":
355360
print("This resulted in the stderr: \n%s" % err.decode())
356361

362+
def get_mujoco_version():
363+
with open("./libs/mujoco/version.txt") as f:
364+
return f.read().strip()
365+
366+
def is_conan_package_available(ref: str):
367+
"""
368+
Run 'conan list' and return True if package exists in local or remote caches.
369+
"""
370+
try:
371+
output = subprocess.check_output(
372+
[sys.executable, "-m", "conans.conan", "list", ref, "-c", "-f", "json", "-verror"],
373+
stderr=subprocess.STDOUT,
374+
universal_newlines=True
375+
)
376+
parsed = json.loads(output)
377+
return any( "error" not in v for v in parsed.values() )
378+
except subprocess.CalledProcessError:
379+
return False
380+
381+
def conan_create_mujoco(print_fn: Optional[Callable[[str], None]] = print):
382+
"""
383+
If the 'mujoco/VERSION' package is not found in any remote or the local cache,
384+
then the mujoco project (as defined in '/libs/mujoco/conanfile.py') is created
385+
into the local cache.
386+
"""
387+
ref = f"mujoco/{get_mujoco_version()}"
388+
if not is_conan_package_available(ref):
389+
if print_fn is not None:
390+
print_fn(f"Package {ref} not found locally, creating it...")
391+
# Run 'conan create' in the external recipe directory
392+
subprocess.run([sys.executable, "-m", "conans.conan", "create", ".", "-s" ,"compiler.cppstd=17"], cwd="./libs/mujoco" )
393+
else:
394+
if print_fn is not None:
395+
print_fn(f"Package {ref} already available, skipping creation.")
396+
357397
if __name__ == "__main__":
358398
# make sure conan is configured to use the libstdc++11 by default
359399
# XXX: This needs to be run before dispatching to Conan (i.e. outside of the
360400
# ConanFile object), because it affects the configuration of the first run.
361401
# (Running it here fixes https://github.com/AVSLab/basilisk/issues/525)
362402
try:
363-
subprocess.check_output(["conan", "profile", "detect", "--exist-ok"])
403+
subprocess.check_output([sys.executable, "-m", "conans.conan", "profile", "detect", "--exist-ok"])
364404
except:
365405
# if profile already exists the above command returns an error. Just ignore in this
366406
# case. We don't want to overwrite an existing profile file
@@ -406,12 +446,24 @@ def add_basilisk_to_sys_path(self):
406446
genMod.createCModule()
407447
print("Done")
408448

449+
# If we're missing MuJoCo, create the conan package
450+
if args.mujoco:
451+
conan_create_mujoco()
452+
453+
if args.mujocoReplay:
454+
print(f"{statusColor}Building 'replay' tool, since '--mujocoReplay true' was used")
455+
try:
456+
subprocess.check_output([sys.executable, "-m", "conans.conan", "build", ".", "-s" ,"compiler.cppstd=17", "--build=missing"], cwd="./src/utilities/mujocoUtils" )
457+
except:
458+
raise RuntimeError("Failed to install MuJoCo replay! See error above.")
459+
409460
# setup conan install command arguments
410461
conanInstallList = list()
411462
conanInstallList.append(f'{sys.executable} -m conans.conan install . --build=missing')
412463
conanInstallList.append(' -s build_type=' + str(args.buildType))
464+
conanInstallList.append(' -s compiler.cppstd=17')
413465
conanBuildOptionsList = list() # setup list of conan build arguments
414-
# The following options go to both conan install and build commands
466+
conanBuildOptionsList.append(' -s compiler.cppstd=17')
415467
if args.generator:
416468
conanBuildOptionsList.append(' -o "&:generator=' + str(args.generator) + '"')
417469
for opt, value in bskModuleOptionsBool.items():

docs/source/Install/installBuild.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ The script accepts the following options to customize this process.
9696
- String
9797
- Empty
9898
- path to external modules folder, see :ref:`buildExtModules`
99+
* - ``mujoco``
100+
- Boolean
101+
- False
102+
- :beta:`Mujoco Support` Includes the `MuJoCo <https://mujoco.org>`_ dependencies
103+
* - ``mujocoReplay``
104+
- Boolean
105+
- False
106+
- :beta:`Mujoco Support` Includes the `MuJoCo <https://mujoco.org>`_ visualization dependencies
99107

100108
Thus, for example, to create a build with ``opNav`` modes enabled, but no :ref:`vizInterface`, and using a
101109
clean distribution folder, and that is built right away, you could use::

docs/source/Install/pipInstall.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
.. _pipInstall:
55

6-
Advanced: (Beta) Building and Installing Pre-Compiled Basilisk Wheels
7-
=====================================================================
6+
Advanced: Building and Installing Pre-Compiled Basilisk Wheels
7+
==============================================================
88

99
.. warning::
1010

11-
This method of building Basilisk is currently a beta feature, and should only be attempted by advanced users
11+
:beta:`Pip Wheel Support` This method of building Basilisk is currently a beta feature, and should only be attempted by advanced users
1212
familiar with `Python packaging and distribution
1313
<https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/>`_.
1414
This method is not yet guaranteed to work on every platform, and there are still some annoyances

docs/source/Learn/makingModules/advancedTopics.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ This section covers advanced BSK module writing topics.
99
:maxdepth: 2
1010

1111
advancedTopics/creatingDynObject
12-
13-
12+
advancedTopics/mujocoDynObject

0 commit comments

Comments
 (0)