Initial open sourcing of MuJoCo.
PiperOrigin-RevId: 450374687 Change-Id: Ie3225a46ce095fc28ae8e63c326a640261f562bb
This commit is contained in:
committed by
Copybara-Service
parent
0e5d062302
commit
1913a02b40
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**How to submit a good bug report**
|
||||
|
||||
- Are you sure this is a bug? If not, consider using the "Ask for help" or "Feature request" templates.
|
||||
|
||||
- Use a clear and descriptive title.
|
||||
|
||||
- Make it easy to reproduce the problem.
|
||||
|
||||
- Include a ***minimal*** model that demonstrates the problem. If the model is small, include it as inline XML. If it requires binary assets, attach it as a zip file.
|
||||
|
||||
- Include a screenshot or video, if relevant.
|
||||
|
||||
- Include the following context:
|
||||
- Operating system.
|
||||
- MuJoCo version (and if the bug is new, the version where it used to work).
|
||||
- For Python issues, what bindings are you using (i.e `mujoco`, `dm_control`, `mujoco-py`)?
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for MuJoCo
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Help
|
||||
about: Ask for help with MuJoCo
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**How to ask for help**
|
||||
|
||||
- Take a step back and tell us what you're trying to accomplish, and in what context. The more information you give, the better the answers you will get.
|
||||
|
||||
- If relevant, include a ***minimal*** model that demonstrates the problem. If the model is small, include it as inline XML. If it requires binary assets, attach it as a zip file.
|
||||
|
||||
- Include a screenshot or video, if relevant.
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# Make CMAKE_C_VISIBILITY_PRESET work properly.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||
# INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
# Default to GLVND if available.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0072 NEW)
|
||||
# Avoid BUILD_SHARED_LIBS getting overridden by an option() in ccd.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
|
||||
# This line has to appear before 'PROJECT' in order to be able to disable incremental linking
|
||||
set(MSVC_INCREMENTAL_DEFAULT ON)
|
||||
|
||||
project(
|
||||
mujoco
|
||||
VERSION 2.2.0
|
||||
DESCRIPTION "MuJoCo Physics Simulator"
|
||||
HOMEPAGE_URL "https://mujoco.org"
|
||||
)
|
||||
|
||||
enable_language(C)
|
||||
enable_language(CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
|
||||
option(MUJOCO_BUILD_EXAMPLES "Build samples for MuJoCo" ON)
|
||||
option(MUJOCO_BUILD_TESTS "Build tests for MuJoCo" ON)
|
||||
option(MUJOCO_TEST_PYTHON_UTIL "Build and test utility libraries for Python bindings" ON)
|
||||
|
||||
if(APPLE AND MUJOCO_BUILD_EXAMPLES)
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
endif()
|
||||
|
||||
include(MujocoOptions)
|
||||
include(MujocoMacOS)
|
||||
include(MujocoDependencies)
|
||||
|
||||
set(MUJOCO_HEADERS
|
||||
include/mujoco/mjdata.h
|
||||
include/mujoco/mjexport.h
|
||||
include/mujoco/mjmodel.h
|
||||
include/mujoco/mjrender.h
|
||||
include/mujoco/mjtnum.h
|
||||
include/mujoco/mjui.h
|
||||
include/mujoco/mjvisualize.h
|
||||
include/mujoco/mjxmacro.h
|
||||
include/mujoco/mujoco.h
|
||||
)
|
||||
|
||||
add_library(mujoco SHARED)
|
||||
target_include_directories(
|
||||
mujoco
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/>
|
||||
PRIVATE src
|
||||
)
|
||||
|
||||
add_subdirectory(src/engine)
|
||||
add_subdirectory(src/user)
|
||||
add_subdirectory(src/xml)
|
||||
add_subdirectory(src/render)
|
||||
add_subdirectory(src/ui)
|
||||
|
||||
target_compile_definitions(mujoco PRIVATE _GNU_SOURCE CCD_STATIC_DEFINE MUJOCO_DLL_EXPORTS)
|
||||
if(MUJOCO_ENABLE_AVX_INTRINSICS)
|
||||
target_compile_definitions(mujoco PUBLIC mjUSEPLATFORMSIMD)
|
||||
endif()
|
||||
|
||||
target_compile_options(
|
||||
mujoco
|
||||
PRIVATE ${AVX_COMPILE_OPTIONS}
|
||||
${MUJOCO_MACOS_COMPILE_OPTIONS}
|
||||
${EXTRA_COMPILE_OPTIONS}
|
||||
${MUJOCO_CXX_FLAGS}
|
||||
)
|
||||
target_link_options(
|
||||
mujoco
|
||||
PRIVATE
|
||||
${MUJOCO_MACOS_LINK_OPTIONS}
|
||||
${EXTRA_LINK_OPTIONS}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
mujoco
|
||||
PRIVATE ccd
|
||||
lodepng
|
||||
qhullstatic_r
|
||||
tinyobjloader
|
||||
tinyxml2
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
mujoco PROPERTIES VERSION "${mujoco_VERSION}" PUBLIC_HEADER "${MUJOCO_HEADERS}"
|
||||
)
|
||||
|
||||
# CMake's built-in FRAMEWORK option doesn't give us control over the dylib name inside the
|
||||
# Framework. We instead make our own Framework here.
|
||||
if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
|
||||
include(DuplicateTarget)
|
||||
duplicate_target(
|
||||
TARGET
|
||||
mujoco
|
||||
NEW_TARGET_NAME
|
||||
mujoco_framework
|
||||
)
|
||||
|
||||
# Do not add mujoco::mujoco to the ALL target. We do this to speed up the
|
||||
# build assuming the user is interested in the Frameworks.
|
||||
set_target_properties(mujoco PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
set(TAPI
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/tapi"
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dist/Info.plist.framework.in
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dist/Info.framework.plist
|
||||
)
|
||||
set_target_properties(
|
||||
mujoco_framework
|
||||
PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/mujoco.framework/Versions/A"
|
||||
BUILD_WITH_INSTALL_NAME_DIR TRUE
|
||||
INSTALL_NAME_DIR "@rpath/mujoco.framework/Versions/A"
|
||||
OUTPUT_NAME "mujoco"
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET mujoco_framework
|
||||
POST_BUILD
|
||||
COMMAND mkdir -p $<TARGET_FILE_DIR:mujoco_framework>/Headers
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ${MUJOCO_HEADERS}
|
||||
$<TARGET_FILE_DIR:mujoco_framework>/Headers
|
||||
COMMAND mkdir -p $<TARGET_FILE_DIR:mujoco_framework>/Modules
|
||||
COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/dist/module.modulemap
|
||||
$<TARGET_FILE_DIR:mujoco_framework>/Modules
|
||||
COMMAND mkdir -p $<TARGET_FILE_DIR:mujoco_framework>/Resources
|
||||
COMMAND mv ${CMAKE_CURRENT_SOURCE_DIR}/dist/Info.framework.plist
|
||||
$<TARGET_FILE_DIR:mujoco_framework>/Resources/Info.plist
|
||||
COMMAND ln -fhs A $<TARGET_FILE_DIR:mujoco_framework>/../Current
|
||||
COMMAND ${TAPI} stubify $<TARGET_FILE:mujoco_framework> -o
|
||||
$<TARGET_FILE_DIR:mujoco_framework>/../../mujoco.tbd
|
||||
COMMAND ln -fhs Versions/Current/Headers $<TARGET_FILE_DIR:mujoco_framework>/../../Headers
|
||||
COMMAND ln -fhs Versions/Current/Modules $<TARGET_FILE_DIR:mujoco_framework>/../../Modules
|
||||
COMMAND ln -fhs Versions/Current/Resources $<TARGET_FILE_DIR:mujoco_framework>/../../Resources
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add a namespace alias to mujoco to be used by the examples.
|
||||
# This simulates the install interface when building with sources.
|
||||
add_library(mujoco::mujoco ALIAS mujoco)
|
||||
|
||||
add_subdirectory(model)
|
||||
|
||||
if(MUJOCO_BUILD_EXAMPLES)
|
||||
add_subdirectory(sample)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING AND MUJOCO_BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING AND MUJOCO_TEST_PYTHON_UTIL)
|
||||
enable_testing()
|
||||
add_subdirectory(python/mujoco/util)
|
||||
endif()
|
||||
|
||||
# Install the libraries.
|
||||
install(
|
||||
TARGETS mujoco
|
||||
EXPORT ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT dev
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT dev
|
||||
)
|
||||
|
||||
set(CONFIG_PACKAGE_LOCATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
# Generate and install the mujocoTargets.cmake file. This defines the targets as
|
||||
# IMPORTED libraries for downstream users.
|
||||
install(
|
||||
EXPORT ${PROJECT_NAME}
|
||||
DESTINATION ${CONFIG_PACKAGE_LOCATION}
|
||||
NAMESPACE mujoco::
|
||||
FILE "${PROJECT_NAME}Targets.cmake"
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
VERSION ${mujoco_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
configure_package_config_file(
|
||||
cmake/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION ${CONFIG_PACKAGE_LOCATION}
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION ${CONFIG_PACKAGE_LOCATION}
|
||||
)
|
||||
|
||||
# Install also models into share folder.
|
||||
install(
|
||||
DIRECTORY model
|
||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/mujoco"
|
||||
PATTERN "CMakeLists.txt" EXCLUDE
|
||||
)
|
||||
+104
-13
@@ -1,25 +1,116 @@
|
||||
# How to Contribute
|
||||
# Contributing to MuJoCo
|
||||
|
||||
We are still in the process of preparing the MuJoCo codebase for open-sourcing,
|
||||
however the full source code for the Python bindings and the Unity plugin are
|
||||
already released. You are welcome to send us pull requests to improve any part
|
||||
of this repository.
|
||||
We intend for MuJoCo to be a true community-driven project and look forward to
|
||||
accepting your contributions!
|
||||
|
||||
## Contributor License Agreement
|
||||
## Before you contribute
|
||||
|
||||
### Documentation, forums
|
||||
|
||||
Please read MuJoCo's [documentation](https://mujoco.readthedocs.io) and look
|
||||
through current topics on our GitHub
|
||||
[issues](https://github.com/deepmind/mujoco/issues) and
|
||||
[discussions](https://github.com/deepmind/mujoco/discussions) pages.
|
||||
|
||||
### Contributor License Agreement
|
||||
|
||||
Contributions to this project must be accompanied by a Contributor License
|
||||
Agreement. You (or your employer) retain the copyright to your contribution,
|
||||
this simply gives us permission to use and redistribute your contributions as
|
||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
||||
your current agreements on file or to sign a new one.
|
||||
Agreement (CLA). You (or your employer) retain the copyright to your
|
||||
contribution; this simply gives us permission to use and redistribute your
|
||||
contributions as part of the project. Head over to
|
||||
<https://cla.developers.google.com/> to see your current agreements on file or
|
||||
to sign a new one.
|
||||
|
||||
You generally only need to submit a CLA once, so if you've already submitted one
|
||||
(even if it was for a different project), you probably don't need to do it
|
||||
again.
|
||||
|
||||
## Code reviews
|
||||
## Contributing
|
||||
|
||||
All submissions require review. Please use GitHub pull requests for this
|
||||
purpose. Consult
|
||||
### Reporting bugs
|
||||
|
||||
How to submit a good bug report:
|
||||
|
||||
- Use a clear and descriptive title.
|
||||
|
||||
- Make it easy to reproduce the problem. If this requires a model, attach it as
|
||||
a zip file to the bug report. The model and steps required to reproduce the
|
||||
proplem should be *minimal*, in the sense that irrelevant parts are
|
||||
removed.
|
||||
|
||||
- Clearly state what is the expected behavior.
|
||||
|
||||
- Include an illustrative screenshot, if relevant.
|
||||
|
||||
Try to provide context:
|
||||
|
||||
- If the problem is new, see if you can reproduce it in an older version.
|
||||
What's the most recent version in which the problem doesn't happen?
|
||||
|
||||
- Can you reproduce the problem on multiple platforms?
|
||||
|
||||
### Suggesting enhancements
|
||||
|
||||
Before submitting an enhancement suggestion:
|
||||
|
||||
- Check if you're using the [latest
|
||||
version](https://github.com/deepmind/mujoco/releases/latest) of MuJoCo.
|
||||
|
||||
- Perform a quick [search](https://github.com/deepmind/mujoco/issues) to see if
|
||||
the enhancement has already been suggested. If it has, add a comment to the
|
||||
existing issue instead of opening a new one.
|
||||
|
||||
How to submit a good enhacement suggestion:
|
||||
|
||||
- Use a clear and descriptive title.
|
||||
|
||||
- Describe the current behaviour and the behavior which you hope to see instead.
|
||||
|
||||
- Explain why this enhancement would be useful.
|
||||
|
||||
- Specify the version of MuJoCo and platform/OS you are using.
|
||||
|
||||
### Contributing code
|
||||
|
||||
- Except for small and straightforward bugfixes, please get in touch with us
|
||||
before you start working on a contribution so that we can help and possibly
|
||||
guide you. Coordinating up front makes it much easier to avoid frustration later
|
||||
on.
|
||||
|
||||
- All submissions require review. Please use GitHub pull requests for this
|
||||
purpose. Please consult
|
||||
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||
information on pull requests.
|
||||
|
||||
- Write tests. MuJoCo uses [googletest](https://github.com/google/googletest)
|
||||
for C++ tests, [absltest](https://abseil.io/docs/python/guides/testing) for
|
||||
Python binding code and [nunit](https://nunit.org/) for C# code in the Unity
|
||||
plugin. In most cases, a pull request will only be accepted if it includes
|
||||
tests. MuJoCo's internal codebase is currently lacking in test coverage. If you
|
||||
want to modify a function that isn't covered by tests, you'll be expected to
|
||||
contribute tests for the existing functionality, not just your modification. In
|
||||
fact, writing a test for existing code is a great way to get started with
|
||||
contributions.
|
||||
|
||||
- Resolve compiler warnings.
|
||||
|
||||
- All existing tests must pass.
|
||||
|
||||
- Follow the [Style Guide](./STYLEGUIDE.md). In particular, adequately comment
|
||||
your code.
|
||||
|
||||
- Make small pull requests. We will likely ask you to split up a large pull
|
||||
request into self-contained, smaller ones, especially if the PR is trying to
|
||||
achieve multiple things.
|
||||
|
||||
- Respond to reviewers. Please be responsive to any questions and comments.
|
||||
|
||||
Once you have met all the requirements, your code will be merged.
|
||||
Thanks for improving MuJoCo!
|
||||
|
||||
|
||||
|
||||
### Community guidelines
|
||||
|
||||
This project follows Google's
|
||||
[Open Source Community Guidelines](https://opensource.google/conduct/).
|
||||
|
||||
@@ -6,77 +6,50 @@ in robotics, biomechanics, graphics and animation, machine learning, and other
|
||||
areas which demand fast and accurate simulation of articulated structures
|
||||
interacting with their environment.
|
||||
|
||||
DeepMind has acquired MuJoCo, and we are currently making preparations to open
|
||||
source the codebase. In the meantime, MuJoCo is available for download as a free
|
||||
and unrestricted precompiled binary under the Apache 2.0 license from
|
||||
the [GitHub Releases page](https://github.com/deepmind/mujoco/releases).
|
||||
|
||||
MuJoCo's source code will be released through this GitHub repository once it is
|
||||
ready. In the meantime, the repository hosts MuJoCo's documentation, C header
|
||||
files for its public API, sample program code, along with the full source code
|
||||
for the Python bindings and Unity plugin. If you wish to report bugs or make
|
||||
feature requests, please file them as [GitHub Issues]. You are also welcome to
|
||||
send us pull requests to improve anything that has been released into this
|
||||
repository.
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
MuJoCo is a compiled library with a C API, intended for researchers and
|
||||
developers. The runtime simulation module is tuned to maximize performance and
|
||||
operates on low-level data structures which are preallocated by the built-in XML
|
||||
parser and compiler. The user defines models in the native MJCF scene
|
||||
description language -- an XML file format designed to be as human readable and
|
||||
editable as possible. URDF model files can also be loaded. The library includes
|
||||
interactive visualization with a native GUI, rendered in OpenGL. MuJoCo further
|
||||
exposes a large number of utility functions for computing physics-related
|
||||
quantities, not necessarily in a simulation loop. Features include
|
||||
|
||||
- Simulation in generalized coordinates, avoiding joint violations.
|
||||
|
||||
- Inverse dynamics that are well-defined even in the presence of contacts.
|
||||
|
||||
- Unified continuous-time formulation of constraints via convex optimization.
|
||||
|
||||
- Constraints include soft contacts, limits, dry friction, equality
|
||||
constraints.
|
||||
|
||||
- Simulation of particle systems, cloth, rope and soft objects.
|
||||
|
||||
- Actuators including motors, cylinders, muscles, tendons, slider-cranks.
|
||||
|
||||
- Choice of Newton, Conjugate Gradient, or Projected Gauss-Seidel solvers.
|
||||
|
||||
- Choice of pyramidal or elliptic friction cones, dense or sparse Jacobians.
|
||||
|
||||
- Choice of Euler or Runge-Kutta numerical integrators.
|
||||
|
||||
- Multi-threaded sampling and finite-difference approximations.
|
||||
|
||||
- Intuitive XML model format (called MJCF) and built-in model compiler.
|
||||
|
||||
- Cross-platform GUI with interactive 3D visualization in OpenGL.
|
||||
|
||||
- Run-time module written in ANSI C and hand-tuned for performance.
|
||||
|
||||
[Python bindings](https://github.com/deepmind/mujoco/tree/main/python) and a
|
||||
[plugin for the Unity game engine](https://github.com/deepmind/mujoco/tree/main/unity)
|
||||
are also provided and are actively supported by the MuJoCo development team.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
MuJoCo binaries are currently built for Linux (x86-64 and AArch64),
|
||||
Windows (x86-64 only), and macOS. If you require a build for a different
|
||||
platform, please let us know via [GitHub Issues] or
|
||||
[Discussions](https://github.com/deepmind/mujoco/discussions).
|
||||
This repository is maintained by DeepMind, please see our [acquisition] and
|
||||
[open sourcing] announcements.
|
||||
|
||||
MuJoCo has a C API and is intended for researchers and developers. The runtime
|
||||
simulation module is tuned to maximize performance and operates on low-level
|
||||
data structures that are preallocated by the built-in XML compiler. The library
|
||||
includes interactive visualization with a native GUI, rendered in OpenGL. MuJoCo
|
||||
further exposes a large number of utility functions for computing physics-
|
||||
related quantities. We also provide Python bindings and a plug-in for the Unity
|
||||
game engine.
|
||||
|
||||
## Documentation
|
||||
|
||||
MuJoco's current documentation is available at [mujoco.org/book], which is
|
||||
serving Sphinx-based webpages derived from the ReStructuredText
|
||||
[documentation source files].
|
||||
MuJoCo's documentation is available at [mujoco.readthedocs.io], which serves
|
||||
webpages derived from the [documentation source files].
|
||||
|
||||
## Releases
|
||||
|
||||
Versioned releases are available as precompiled binaries from the GitHub
|
||||
[releases page], built for Linux (x86-64 and AArch64), Windows (x86-64 only),
|
||||
and macOS (universal). This is the recommended way to use the software.
|
||||
|
||||
Users who wish to build MuJoCo from source, please consult the [build from
|
||||
source] section of the documentation. However, please note that the commit at
|
||||
the tip of the `main` branch branch may be unstable.
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
There are two easy ways to get started with MuJoCo:
|
||||
|
||||
1. **Run `simulate` on your machine.**
|
||||
[This video](https://www.youtube.com/watch?v=0ORsj_E17B0) shows a screen capture
|
||||
of `simulate`, MuJoCo's native interactive viewer. Follow the steps described in
|
||||
the [Getting Started] section of the documentation to get `simulate` running on
|
||||
your machine.
|
||||
|
||||
2. **Explore our online IPython notebooks.**
|
||||
If you are a Python user, you might want to start with our tutorial notebooks,
|
||||
running on Google Colab:
|
||||
|
||||
- The first tutorial focuses on the basic MuJoco Python bindings: [](https://colab.research.google.com/github/deepmind/dm_control/blob/main/dm_control/mujoco/tutorial.ipynb).
|
||||
|
||||
- The second tutorial includes more examples of `dm_control`-specific functionality: [](https://colab.research.google.com/github/deepmind/dm_control/blob/main/tutorial.ipynb).
|
||||
|
||||
|
||||
## Citation
|
||||
@@ -85,19 +58,23 @@ If you use MuJoCo for published research, please cite:
|
||||
|
||||
```
|
||||
@inproceedings{todorov2012mujoco,
|
||||
title={Mujoco: A physics engine for model-based control},
|
||||
title={MuJoCo: A physics engine for model-based control},
|
||||
author={Todorov, Emanuel and Erez, Tom and Tassa, Yuval},
|
||||
booktitle={2012 IEEE/RSJ International Conference on Intelligent Robots and Systems},
|
||||
pages={5026--5033},
|
||||
year={2012},
|
||||
organization={IEEE}
|
||||
organization={IEEE},
|
||||
doi={10.1109/IROS.2012.6386109}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## License and Disclaimer
|
||||
|
||||
Copyright 2021 DeepMind Technologies Limited
|
||||
Copyright 2021 DeepMind Technologies Limited.
|
||||
|
||||
Box collision code ([`engine_collision_box.c`](https://github.com/deepmind/mujoco/tree/main/src/engine/engine_collision_box.c))
|
||||
is Copyright 2016 Svetoslav Kolev.
|
||||
|
||||
ReStructuredText documents, images, and videos in the `doc` directory are made
|
||||
available under the terms of the Creative Commons Attribution 4.0 (CC BY 4.0)
|
||||
@@ -109,7 +86,11 @@ copy of the License at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
This is not an officially supported Google product.
|
||||
|
||||
|
||||
[build from source]: https://mujoco.readthedocs.io/en/latest/programming.html#building-mujoco-from-source
|
||||
[Getting Started]: https://mujoco.readthedocs.io/en/latest/programming.html#getting-started
|
||||
[acquisition]: https://www.deepmind.com/blog/opening-up-a-physics-simulator-for-robotics
|
||||
[open sourcing]: https://www.deepmind.com/blog/open-sourcing-mujoco
|
||||
[releases page]: https://github.com/deepmind/mujoco/releases
|
||||
[GitHub Issues]: https://github.com/deepmind/mujoco/issues
|
||||
[documentation source files]: https://github.com/deepmind/mujoco/tree/main/doc
|
||||
[mujoco.org/book]: https://mujoco.org/book
|
||||
[mujoco.readthedocs.io]: https://mujoco.readthedocs.io
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
# MuJoCo Style Guide
|
||||
|
||||
The MuJoCo codebase follows an internally consistent style that values
|
||||
compactness and readability. Please try to follow the style guide as closely as
|
||||
possible in your code contributions.
|
||||
|
||||
### Scope of this guide
|
||||
|
||||
MuJoCo has three main code categories:
|
||||
|
||||
1. **C code:** MuJoCo's core codebase. It consists of public headers under
|
||||
`include/` and C source files and internal headers under `src/`. This style
|
||||
guide primarily concerns itself with this category.
|
||||
|
||||
2. **Legacy C++:** Files under `src/user/` and `src/xml/`. These do not
|
||||
necessarily follow best C++ practices. We intend to gradually replace these with
|
||||
new code that follows the [Google C++
|
||||
style](https://google.github.io/styleguide/cppguide.html) over time.
|
||||
|
||||
3. **New code:** This includes C++ files under `test/` and `python/` and C#
|
||||
files under `unity/`. Added by DeepMind engineers, this code adheres to the
|
||||
[Google style](https://google.github.io/styleguide/).
|
||||
|
||||
### General principles
|
||||
|
||||
Where any aspect of coding style is not explicitly spelled out in this guide,
|
||||
the following principle is followed:
|
||||
|
||||
| Maximise consistency with the rest of the code. |
|
||||
| --- |
|
||||
|
||||
If there is a contradiction between this guide and existing code, the guide
|
||||
takes precedence. Additional principles include:
|
||||
|
||||
- Follow the [naming conventions](https://mujoco.readthedocs.io/en/latest/programming.html#naming-convention).
|
||||
- Be sparing with horizontal space: Try to keep lines short, avoid line-breaks
|
||||
where possble.
|
||||
- Be generous with vertical space: Empty lines between code blocks are good.
|
||||
- Keep names short.
|
||||
- Inline comments are part of the code, treat them as such.
|
||||
- Use American English in comments and documentation.
|
||||
|
||||
### Specific rules for C code
|
||||
|
||||
Over time, this style guide will be expanded to cover most aspects of C
|
||||
programming in the MuJoCo codebase. In the meantime, it is usually enough to
|
||||
inspect existing code and try to follow its example.
|
||||
|
||||
If there are any consistent coding patterns that are specific to the MuJoCo
|
||||
codebase but aren't mentioned in the guide, the guide should be expanded. If you
|
||||
spot such a pattern, feel free to send a PR to update the guide.
|
||||
|
||||
#### Indentation
|
||||
|
||||
2-space indents, using space characters rather than tabs.
|
||||
|
||||
#### Line length
|
||||
|
||||
Line length is 100 characters. In rare situations, like the collision table at
|
||||
the top of
|
||||
[engine_collision_driver.c](https://github.com/deepmind/mujoco/search?q=repo%3Ad
|
||||
eepmind%2Fmujoco+filename%3Aengine_collision_driver.c), longer lines are alowed
|
||||
for readability.
|
||||
|
||||
#### Comments
|
||||
|
||||
MuJoCo makes generous use of short, one-line comments describing the code block
|
||||
just below them. They are considered an essential part of the code. Comments
|
||||
should be:
|
||||
|
||||
- As succinct as possible, while maintaining clarity.
|
||||
- Preceded by an empty line, unless at the top of a block.
|
||||
- Uncapitalized and not terminated by a full-stop.
|
||||
|
||||
A helpful heuristic regarding in-code comments is that the reader should be able
|
||||
to get a sense of what is happening in a function just by reading the comments.
|
||||
|
||||
An exception to the third bullet point above are function declaration comments
|
||||
in public header files which are considered to be docstrings rather than code
|
||||
and are therefore capitalized and terminated by a full stop. These docstrings
|
||||
are required.
|
||||
|
||||
#### Braces
|
||||
|
||||
- MuJoCo uses
|
||||
[attached K&R braces](https://en.wikipedia.org/wiki/Indentation_style#Variant:_mandatory_braces),
|
||||
including for one-line blocks:
|
||||
|
||||
```C
|
||||
// transpose matrix
|
||||
void mju_transpose(mjtNum* res, const mjtNum* mat, int nr, int nc) {
|
||||
for (int i=0; i<nr; i++) {
|
||||
for (int j=0; j<nc; j++) {
|
||||
res[j*nr+i] = mat[i*nc+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Brace-less single line statements are allowed outside of `engine/` code, for
|
||||
similar, repeated blocks, that do not contain flow control statements (`return`,
|
||||
`continue`, etc.). For an example of this exception, inspect the [`mjCModel`
|
||||
destructor](https://github.com/deepmind/mujoco/search?q=repo%3Adeepmind%2Fmujoco+filename%3Auser_model.cc).
|
||||
|
||||
- Unattached braces are allowed in `if/else` blocks, when inserting a comment
|
||||
before the `else`:
|
||||
|
||||
```C
|
||||
// rotate vector by quaternion
|
||||
void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]) {
|
||||
// null quat: copy vec
|
||||
if (quat[0]==1 && quat[1]==0 && quat[2]==0 && quat[3]==0) {
|
||||
mju_copy3(res, vec);
|
||||
}
|
||||
|
||||
// regular processing
|
||||
else {
|
||||
mjtNum mat[9];
|
||||
mju_quat2Mat(mat, quat);
|
||||
mju_rotVecMat(res, vec, mat);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Spacing
|
||||
|
||||
- MuJoCo encourages judicious use of spacing around operators to promote
|
||||
readability. For example below, note the lack of spaces around the
|
||||
multiplication operator, and the aligning spaces in the second and fourth
|
||||
assignments:
|
||||
|
||||
```C
|
||||
// time-derivative of quaternion, given 3D rotational velocity
|
||||
void mju_derivQuat(mjtNum res[4], const mjtNum quat[4], const mjtNum vel[3]) {
|
||||
res[0] = 0.5*(-vel[0]*quat[1] - vel[1]*quat[2] - vel[2]*quat[3]);
|
||||
res[1] = 0.5*( vel[0]*quat[0] + vel[1]*quat[3] - vel[2]*quat[2]);
|
||||
res[2] = 0.5*(-vel[0]*quat[3] + vel[1]*quat[0] + vel[2]*quat[1]);
|
||||
res[3] = 0.5*( vel[0]*quat[2] - vel[1]*quat[1] + vel[2]*quat[0]);
|
||||
}
|
||||
```
|
||||
|
||||
- Spaces are not allowed around comparison operators in `for` statements and
|
||||
inside array subscripts `[]`. For an example, inspect the `mju_transpose`
|
||||
implementation above.
|
||||
|
||||
- Three empty lines between function declarations.
|
||||
|
||||
#### Variable declarations
|
||||
|
||||
Historically the MuJoCo C codebase used exclusively C89-style variable
|
||||
declarations, with all stack variables pre-declared at the top of the function.
|
||||
We are in the process of migrating the code to the C99 convention of declaring
|
||||
variables at the narrowest possible scope. For example iterator variables in
|
||||
for-loops are mostly declared in the narrow scope, as in the `mju_transpose`
|
||||
example above.
|
||||
|
||||
New code should use the C99 convention. When editing an existing function,
|
||||
please move existing variable declarations into local scope. Pull requests
|
||||
helping us to complete the migration are very welcome.
|
||||
@@ -0,0 +1,177 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#.rst:
|
||||
# duplicate_target
|
||||
# ----------------------
|
||||
#
|
||||
# Duplicates the specified target.
|
||||
#
|
||||
# duplicate_target(TARGET target NEW_TARGET_NAME new_target_name)
|
||||
#
|
||||
# Duplicates the specified target by creating a new target with the name
|
||||
# specified by ``NEW_TARGET_NAME`` and copying all properties defined by
|
||||
# ``TARGET``.
|
||||
# The command has the following parameters:
|
||||
#
|
||||
# Arguments:
|
||||
# - ``TARGET`` Target to be duplicated.
|
||||
# - ``NEW_TARGET_NAME`` name of the new target.
|
||||
#
|
||||
|
||||
if(COMMAND duplicate_target)
|
||||
return()
|
||||
endif()
|
||||
|
||||
macro(duplicate_target)
|
||||
# Parse arguments.
|
||||
set(options)
|
||||
set(one_value_args TARGET NEW_TARGET_NAME)
|
||||
set(multi_value_args)
|
||||
cmake_parse_arguments(
|
||||
_ARGS
|
||||
"${options}"
|
||||
"${one_value_args}"
|
||||
"${multi_value_args}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
# Check required variables are defined.
|
||||
if(NOT _ARGS_TARGET)
|
||||
message(FATAL_ERROR "duplicate_target: TARGET must be specified.")
|
||||
endif()
|
||||
if(NOT _ARGS_NEW_TARGET_NAME)
|
||||
message(FATAL_ERROR "duplicate_target: NEW_TARGET_NAME must be specified.")
|
||||
endif()
|
||||
|
||||
# Check for the target to exist.
|
||||
if(NOT TARGET ${_ARGS_TARGET})
|
||||
message(FATAL_ERROR "duplicate_target: TARGET ${_ARGS_TARGET} not found.")
|
||||
endif()
|
||||
|
||||
# Non-exausitve list.
|
||||
set(PROPERTIES_TO_SKIP)
|
||||
get_target_property(TARGET_TYPE ${_ARGS_TARGET} TYPE)
|
||||
if(${TARGET_TYPE} STREQUAL "STATIC_LIBRARY")
|
||||
add_library(${_ARGS_NEW_TARGET_NAME} STATIC)
|
||||
list(APPEND PROPERTIES_TO_SKIP "IMPORTED_GLOBAL")
|
||||
elseif(${TARGET_TYPE} STREQUAL "SHARED_LIBRARY")
|
||||
add_library(${_ARGS_NEW_TARGET_NAME} SHARED)
|
||||
list(APPEND PROPERTIES_TO_SKIP "IMPORTED_GLOBAL")
|
||||
elseif(${TARGET_TYPE} STREQUAL "OBJECT_LIBRARY")
|
||||
add_library(${_ARGS_NEW_TARGET_NAME} OBJECT)
|
||||
list(APPEND PROPERTIES_TO_SKIP "IMPORTED_GLOBAL")
|
||||
elseif(${TARGET_TYPE} STREQUAL "INTERFACE_LIBRARY")
|
||||
add_library(${_ARGS_NEW_TARGET_NAME} INTERFACE)
|
||||
elseif(${TARGET_TYPE} STREQUAL "EXECUTABLE")
|
||||
add_executable(${_ARGS_NEW_TARGET_NAME})
|
||||
list(APPEND PROPERTIES_TO_SKIP "IMPORTED_GLOBAL")
|
||||
endif()
|
||||
|
||||
set(IGNORED_PROPERTIES "HEADER_SETS;INTERFACE_HEADER_SETS;NAME;TYPE")
|
||||
|
||||
# Get all CMake target properties.
|
||||
if(NOT CMAKE_ALL_PROPERTY_LIST)
|
||||
execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE ALL_PROPERTIES)
|
||||
|
||||
# Convert command output into a CMake list
|
||||
string(
|
||||
REGEX
|
||||
REPLACE ";"
|
||||
"\\\\;"
|
||||
ALL_PROPERTIES
|
||||
"${ALL_PROPERTIES}"
|
||||
)
|
||||
string(
|
||||
REGEX
|
||||
REPLACE "\n"
|
||||
";"
|
||||
ALL_PROPERTIES
|
||||
"${ALL_PROPERTIES}"
|
||||
)
|
||||
|
||||
# Post process the properties. We:
|
||||
# - Remove all properties listed in ``IGNORED_PROPERTIES``.
|
||||
# - Remove LOCATION as it should not be accessed, See https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i
|
||||
# - Substitute <CONFIG> with all the possible build types. This is needed for multi-config generators as they can change the type of build without invoking again CMake.
|
||||
set(CMAKE_ALL_PROPERTY_LIST "")
|
||||
foreach(PROPERTY ${ALL_PROPERTIES})
|
||||
# Skip reading the LOCAION property as they should not be read.
|
||||
# See https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i
|
||||
if(PROPERTY STREQUAL "LOCATION"
|
||||
OR PROPERTY MATCHES "^LOCATION_"
|
||||
OR PROPERTY MATCHES "_LOCATION$"
|
||||
)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
set(_ignore OFF)
|
||||
foreach(_pro ${IGNORED_PROPERTIES})
|
||||
if(PROPERTY STREQUAL ${_pro})
|
||||
set(_ignore ON)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_ignore)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
string(FIND ${PROPERTY} "<CONFIG>" FOUND)
|
||||
if(${FOUND} EQUAL -1)
|
||||
# Simply append the property.
|
||||
list(APPEND CMAKE_ALL_PROPERTY_LIST ${PROPERTY})
|
||||
else()
|
||||
# Iterate on the build types to add the correct property.
|
||||
foreach(BUILD_TYPE ${BUILD_TYPES})
|
||||
string(
|
||||
REPLACE "<CONFIG>"
|
||||
"${BUILD_TYPE}"
|
||||
CONFIG_PROPERTY
|
||||
${PROPERTY}
|
||||
)
|
||||
list(APPEND CMAKE_ALL_PROPERTY_LIST ${CONFIG_PROPERTY})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
endif()
|
||||
|
||||
foreach(PROPERTY ${CMAKE_ALL_PROPERTY_LIST})
|
||||
# Search if we should skip this property.
|
||||
|
||||
list(
|
||||
FIND
|
||||
PROPERTIES_TO_SKIP
|
||||
${PROPERTY}
|
||||
SHOULD_SKIP
|
||||
)
|
||||
if(${SHOULD_SKIP} GREATER_EQUAL 0)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# First check if the property was set on the target
|
||||
get_property(
|
||||
PROPERTY_FOUND
|
||||
TARGET ${_ARGS_TARGET}
|
||||
PROPERTY ${PROPERTY}
|
||||
SET
|
||||
)
|
||||
if(PROPERTY_FOUND)
|
||||
get_target_property(PROPERTY_VALUE ${_ARGS_TARGET} ${PROPERTY})
|
||||
set_target_properties(${_ARGS_NEW_TARGET_NAME} PROPERTIES ${PROPERTY} "${PROPERTY_VALUE}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
+25
-14
@@ -31,8 +31,9 @@
|
||||
#
|
||||
# Arguments:
|
||||
# - ``USE_SYSTEM_PACKAGE`` one-value argument on whether to search for the
|
||||
# package in the system (ON) or whether to fetch the library from a git
|
||||
# repository (OFF).
|
||||
# package in the system (ON) or whether to fetch the library using
|
||||
# FetchContent from the specified Git repository (OFF). Note that
|
||||
# FetchContent variables will override this behaviour.
|
||||
# - ``PACKAGE_NAME`` name of the system-package. Ignored if
|
||||
# ``USE_SYSTEM_PACKAGE`` is ``OFF``.
|
||||
# - ``LIBRARY_NAME`` name of the library. Ignored if
|
||||
@@ -41,9 +42,19 @@
|
||||
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||
# - ``GIT_TAG`` tag reference when fetching the library from the git
|
||||
# repository. Ignored if ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||
# - ``PATCH_COMMAND`` Specifies a custom command to patch the sources after an
|
||||
# update. See https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add
|
||||
# for details on the parameter.
|
||||
# - ``TARGETS`` list of targets to be satisfied. If any of these targets are
|
||||
# not currently defined, this macro will attempt to either find or fetch the
|
||||
# package.
|
||||
# - ``EXCLUDE_FROM_ALL`` if specified, the targets are not added to the ``all``
|
||||
# metatarget.
|
||||
#
|
||||
# Note: if ``USE_SYSTEM_PACKAGE`` is ``OFF``, FetchContent will be used to
|
||||
# retrieve the specified targets. It is possible to specify any variable in
|
||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variables to
|
||||
# override this macro behaviour.
|
||||
|
||||
if(COMMAND FindOrFetch)
|
||||
return()
|
||||
@@ -76,10 +87,14 @@ macro(FindOrFetch)
|
||||
if(NOT _ARGS_TARGETS)
|
||||
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
|
||||
endif()
|
||||
|
||||
set(targets_found TRUE)
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: checking for targets in package `${_ARGS_PACKAGE_NAME}`"
|
||||
)
|
||||
foreach(target ${_ARGS_TARGETS})
|
||||
if(NOT TARGET ${target})
|
||||
message(STATUS "mujoco::FindOrFetch: target `${target}` not defined.")
|
||||
message(CHECK_FAIL "target `${target}` not defined.")
|
||||
set(targets_found FALSE)
|
||||
break()
|
||||
endif()
|
||||
@@ -88,16 +103,14 @@ macro(FindOrFetch)
|
||||
# If targets are not found, use `find_package` or `FetchContent...` to get it.
|
||||
if(NOT targets_found)
|
||||
if(${_ARGS_USE_SYSTEM_PACKAGE})
|
||||
message(
|
||||
STATUS
|
||||
"mujoco::FindOrFetch: Attempting to find `${_ARGS_PACKAGE_NAME}` in system packages..."
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: finding `${_ARGS_PACKAGE_NAME}` in system packages..."
|
||||
)
|
||||
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
|
||||
message(STATUS "mujoco::FindOrFetch: Found `${_ARGS_PACKAGE_NAME}` in system packages.")
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(
|
||||
STATUS
|
||||
"mujoco::FindOrFetch: Attempting to fetch `${_ARGS_LIBRARY_NAME}` from `${_ARGS_GIT_REPO}`..."
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: Using FetchContent to retrieve `${_ARGS_LIBRARY_NAME}`"
|
||||
)
|
||||
FetchContent_Declare(
|
||||
${_ARGS_LIBRARY_NAME}
|
||||
@@ -118,11 +131,9 @@ macro(FindOrFetch)
|
||||
else()
|
||||
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
|
||||
endif()
|
||||
message(
|
||||
STATUS "mujoco::FindOrFetch: Fetched `${_ARGS_LIBRARY_NAME}` from `${_ARGS_GIT_REPO}`."
|
||||
)
|
||||
message(CHECK_PASS "Done")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "mujoco::FindOrFetch: `${_ARGS_PACKAGE_NAME}` targets found.")
|
||||
message(CHECK_PASS "found")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Build configuration for third party libraries used in MuJoCo.
|
||||
|
||||
# Override the BUILD_SHARED_LIBS setting, just for building third party libs (since we always want
|
||||
# static libraries). The ccd CMakeLists.txt doesn't expose an option to build a static ccd library,
|
||||
# unless BUILD_SHARED_LIBS is set.
|
||||
|
||||
set(MUJOCO_DEP_VERSION_lodepng
|
||||
48e5364ef48ec2408f44c727657ac1b6703185f8
|
||||
CACHE STRING "Version of `lodepng` to be fetched."
|
||||
)
|
||||
set(MUJOCO_DEP_VERSION_tinyxml2
|
||||
1dee28e51f9175a31955b9791c74c430fe13dc82 # 9.0.0
|
||||
CACHE STRING "Version of `tinyxml2` to be fetched."
|
||||
)
|
||||
set(MUJOCO_DEP_VERSION_tinyobjloader
|
||||
1421a10d6ed9742f5b2c1766d22faa6cfbc56248
|
||||
CACHE STRING "Version of `tinyobjloader` to be fetched."
|
||||
)
|
||||
set(MUJOCO_DEP_VERSION_ccd
|
||||
7931e764a19ef6b21b443376c699bbc9c6d4fba8 # v2.1
|
||||
CACHE STRING "Version of `ccd` to be fetched."
|
||||
)
|
||||
set(MUJOCO_DEP_VERSION_qhull
|
||||
3df027b91202cf179f3fba3c46eebe65bbac3790
|
||||
CACHE STRING "Version of `qhull` to be fetched."
|
||||
)
|
||||
set(MUJOCO_DEP_VERSION_Eigen3
|
||||
b02c384ef4e8eba7b8bdef16f9dc6f8f4d6a6b2b
|
||||
CACHE STRING "Version of `Eigen3` to be fetched."
|
||||
)
|
||||
|
||||
set(MUJOCO_DEP_VERSION_abseil
|
||||
78f9680225b9792c26dfdd99d0bd26c96de53dd4 # Fixes universal builds for macOS
|
||||
CACHE STRING "Version of `abseil` to be fetched."
|
||||
)
|
||||
|
||||
set(MUJOCO_DEP_VERSION_gtest
|
||||
e2239ee6043f73722e7aa812a459f54a28552929 # release-1.11.0
|
||||
CACHE STRING "Version of `gtest` to be fetched."
|
||||
)
|
||||
|
||||
set(MUJOCO_DEP_VERSION_benchmark
|
||||
0d98dba29d66e93259db7daa53a9327df767a415 # v1.6.1
|
||||
CACHE STRING "Version of `benchmark` to be fetched."
|
||||
)
|
||||
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_lodepng)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_tinyxml2)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_tinyobjloader)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_ccd)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_qhull)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_Eigen3)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_abseil)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_gtest)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_benchmark)
|
||||
|
||||
include(FetchContent)
|
||||
include(FindOrFetch)
|
||||
|
||||
# We force all the dependencies to be compiled as static libraries.
|
||||
# TODO(fraromano) Revisit this choice when adding support for install.
|
||||
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS
|
||||
OFF
|
||||
CACHE INTERNAL "Build SHARED libraries"
|
||||
)
|
||||
|
||||
if(NOT TARGET lodepng)
|
||||
FetchContent_Declare(
|
||||
lodepng
|
||||
GIT_REPOSITORY https://github.com/lvandeve/lodepng.git
|
||||
GIT_TAG ${MUJOCO_DEP_VERSION_lodepng}
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(lodepng)
|
||||
if(NOT lodepng_POPULATED)
|
||||
FetchContent_Populate(lodepng)
|
||||
# This is not a CMake project.
|
||||
set(LODEPNG_SRCS ${lodepng_SOURCE_DIR}/lodepng.cpp)
|
||||
set(LODEPNG_HEADERS ${lodepng_SOURCE_DIR}/lodepng.h)
|
||||
add_library(lodepng STATIC ${LODEPNG_HEADERS} ${LODEPNG_SRCS})
|
||||
target_compile_options(lodepng PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(lodepng PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
target_include_directories(lodepng PUBLIC ${lodepng_SOURCE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# TODO(fraromano) We fetch qhull before the other libraries as it needs to go before until https://github.com/qhull/qhull/pull/111 is merged.
|
||||
set(QHULL_ENABLE_TESTING OFF)
|
||||
# We need Git to apply the patch using git apply.
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
qhull
|
||||
LIBRARY_NAME
|
||||
qhull
|
||||
GIT_REPO
|
||||
https://github.com/qhull/qhull.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_qhull}
|
||||
TARGETS
|
||||
qhull
|
||||
# TODO(fraromano) Remove when https://github.com/qhull/qhull/pull/112 is merged.
|
||||
# Do not fail if patch fails. This will happen the second time we run CMake as the sources will be already patched.
|
||||
PATCH_COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
"apply"
|
||||
"-q"
|
||||
"${PROJECT_SOURCE_DIR}/cmake/qhull_fix_testing.patch"
|
||||
"||"
|
||||
"${CMAKE_COMMAND}"
|
||||
"-E"
|
||||
"true"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
# MuJoCo includes a file from libqhull_r which is not exported by the qhull include directories.
|
||||
# Add it to the target.
|
||||
target_include_directories(
|
||||
qhullstatic_r INTERFACE $<BUILD_INTERFACE:${qhull_SOURCE_DIR}/src/libqhull_r>
|
||||
)
|
||||
target_compile_options(qhullstatic_r PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(qhullstatic_r PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
|
||||
set(tinyxml2_BUILD_TESTING OFF)
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
tinyxml2
|
||||
LIBRARY_NAME
|
||||
tinyxml2
|
||||
GIT_REPO
|
||||
https://github.com/leethomason/tinyxml2.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_tinyxml2}
|
||||
TARGETS
|
||||
tinyxml2
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
target_compile_options(tinyxml2 PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(tinyxml2 PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
tinyobjloader
|
||||
LIBRARY_NAME
|
||||
tinyobjloader
|
||||
GIT_REPO
|
||||
https://github.com/tinyobjloader/tinyobjloader.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_tinyobjloader}
|
||||
TARGETS
|
||||
tinyobjloader
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
set(ENABLE_DOUBLE_PRECISION ON)
|
||||
set(CCD_HIDE_ALL_SYMBOLS ON)
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
ccd
|
||||
LIBRARY_NAME
|
||||
ccd
|
||||
GIT_REPO
|
||||
https://github.com/danfis/libccd.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_ccd}
|
||||
TARGETS
|
||||
ccd
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
target_compile_options(ccd PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(ccd PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
|
||||
# libCCD has an unconditional `#define _CRT_SECURE_NO_WARNINGS` on Windows.
|
||||
# TODO(stunya): Remove this after https://github.com/danfis/libccd/pull/77 is merged.
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
# C4005 is the MSVC equivalent of -Wmacro-redefined.
|
||||
target_compile_options(ccd PRIVATE /wd4005)
|
||||
else()
|
||||
target_compile_options(ccd PRIVATE -Wno-macro-redefined)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MUJOCO_BUILD_TESTS)
|
||||
set(ABSL_PROPAGATE_CXX_STD ON)
|
||||
|
||||
# This specific version of Abseil does not have the following variable. We need to work with BUILD_TESTING
|
||||
set(BUILD_TESTING_OLD ${BUILD_TESTING})
|
||||
set(BUILD_TESTING
|
||||
OFF
|
||||
CACHE INTERNAL "Build tests."
|
||||
)
|
||||
|
||||
set(ABSL_BUILD_TESTING OFF)
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
absl
|
||||
LIBRARY_NAME
|
||||
abseil-cpp
|
||||
GIT_REPO
|
||||
https://github.com/abseil/abseil-cpp.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_abseil}
|
||||
TARGETS
|
||||
absl::core_headers
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
set(BUILD_TESTING
|
||||
${BUILD_TESTING_OLD}
|
||||
CACHE BOOL "Build tests." FORCE
|
||||
)
|
||||
|
||||
# Avoid linking errors on Windows by dynamically linking to the C runtime.
|
||||
set(gtest_force_shared_crt
|
||||
ON
|
||||
CACHE BOOL "" FORCE
|
||||
)
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
GTest
|
||||
LIBRARY_NAME
|
||||
googletest
|
||||
GIT_REPO
|
||||
https://github.com/google/googletest.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_gtest}
|
||||
TARGETS
|
||||
gtest
|
||||
gmock
|
||||
gtest_main
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
set(BENCHMARK_EXTRA_FETCH_ARGS "")
|
||||
if(WIN32 AND NOT MSVC)
|
||||
set(BENCHMARK_EXTRA_FETCH_ARGS
|
||||
PATCH_COMMAND
|
||||
"sed"
|
||||
"-i"
|
||||
"-e"
|
||||
"s/-std=c++11/-std=c++14/g"
|
||||
"-e"
|
||||
"s/HAVE_CXX_FLAG_STD_CXX11/HAVE_CXX_FLAG_STD_CXX14/g"
|
||||
"${CMAKE_BINARY_DIR}/_deps/benchmark-src/CMakeLists.txt"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(BENCHMARK_ENABLE_TESTING OFF)
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
benchmark
|
||||
LIBRARY_NAME
|
||||
benchmark
|
||||
GIT_REPO
|
||||
https://github.com/google/benchmark.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_benchmark}
|
||||
TARGETS
|
||||
benchmark::benchmark
|
||||
benchmark::benchmark_main
|
||||
${BENCHMARK_EXTRA_FETCH_ARGS}
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MUJOCO_TEST_PYTHON_UTIL)
|
||||
add_compile_definitions(EIGEN_MPL2_ONLY)
|
||||
if(NOT TARGET eigen)
|
||||
# Support new IN_LIST if() operator.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0057 NEW)
|
||||
|
||||
FetchContent_Declare(
|
||||
Eigen3
|
||||
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
|
||||
GIT_TAG ${MUJOCO_DEP_VERSION_Eigen3}
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(Eigen3)
|
||||
if(NOT Eigen3_POPULATED)
|
||||
FetchContent_Populate(Eigen3)
|
||||
|
||||
# Mark the library as IMPORTED as a workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/15415
|
||||
add_library(Eigen3::Eigen INTERFACE IMPORTED)
|
||||
set_target_properties(
|
||||
Eigen3::Eigen PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${eigen3_SOURCE_DIR}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Reset BUILD_SHARED_LIBS to its previous value
|
||||
set(BUILD_SHARED_LIBS
|
||||
${BUILD_SHARED_LIBS_OLD}
|
||||
CACHE BOOL "Build MuJoCo as a shared library" FORCE
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
option(MUJOCO_HARDEN "Enable build hardening for MuJoCo." OFF)
|
||||
if(MUJOCO_HARDEN
|
||||
AND NOT
|
||||
CMAKE_CXX_COMPILER_ID
|
||||
MATCHES
|
||||
".*Clang.*"
|
||||
)
|
||||
message(FATAL_ERROR "MUJOCO_HARDEN is only supported when building with Clang")
|
||||
endif()
|
||||
|
||||
if(MUJOCO_HARDEN)
|
||||
set(MUJOCO_HARDEN_COMPILE_OPTIONS -D_FORTIFY_SOURCE=2 -fstack-protector)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS -Wl,-bind_at_load)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS -Wl,-z,relro -Wl,-z,now)
|
||||
endif()
|
||||
else()
|
||||
set(MUJOCO_HARDEN_COMPILE_OPTIONS "")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS "")
|
||||
endif()
|
||||
@@ -0,0 +1,38 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if(APPLE)
|
||||
# 10.12 is the oldest version of macOS that supports C++17, launched 2016.
|
||||
set(MUJOCO_MACOSX_VERSION_MIN 10.12)
|
||||
|
||||
# We are setting the -mmacosx-version-min compiler flag directly rather than using the
|
||||
# CMAKE_OSX_DEPLOYMENT_TARGET variable since we do not want to affect choice of SDK,
|
||||
# and also we only want to apply the version restriction locally.
|
||||
set(MUJOCO_MACOS_COMPILE_OPTIONS -mmacosx-version-min=${MUJOCO_MACOSX_VERSION_MIN}
|
||||
-Werror=partial-availability -Werror=unguarded-availability
|
||||
)
|
||||
set(MUJOCO_MACOS_LINK_OPTIONS -mmacosx-version-min=${MUJOCO_MACOSX_VERSION_MIN}
|
||||
-Wl,-no_weak_imports
|
||||
)
|
||||
else()
|
||||
set(MUJOCO_MACOS_COMPILE_OPTIONS "")
|
||||
set(MUJOCO_MACOS_LINK_OPTIONS "")
|
||||
endif()
|
||||
|
||||
function(enforce_mujoco_macosx_min_version)
|
||||
if(APPLE)
|
||||
add_compile_options(${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
add_link_options(${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,106 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Global compilation settings
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # For LLVM tooling
|
||||
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to 'Release' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"Release"
|
||||
CACHE STRING "Choose the type of build, recommanded options are: Debug or Release" FORCE
|
||||
)
|
||||
endif()
|
||||
set(BUILD_TYPES
|
||||
"Debug"
|
||||
"Release"
|
||||
"MinSizeRel"
|
||||
"RelWithDebInfo"
|
||||
)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${BUILD_TYPES})
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Change the default output directory in the build structure. This is not stricly needed, but helps
|
||||
# running in Windows, such that all built executables have DLLs in the same folder as the .exe
|
||||
# files.
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/Gy /Gw /Oi)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-fdata-sections -ffunction-sections)
|
||||
endif()
|
||||
|
||||
# We default to shared library.
|
||||
set(BUILD_SHARED_LIBS
|
||||
ON
|
||||
CACHE BOOL "Build Mujoco as shared library."
|
||||
)
|
||||
|
||||
option(MUJOCO_ENABLE_AVX "Build binaries that require AVX instructions, if possible." ON)
|
||||
option(MUJOCO_ENABLE_AVX_INTRINSICS "Make use of hand-written AVX intrinsics, if possible." ON)
|
||||
option(MUJOCO_ENABLE_RPATH "Enable RPath support when installing Mujoco." ON)
|
||||
mark_as_advanced(MUJOCO_ENABLE_RPATH)
|
||||
|
||||
if(MUJOCO_ENABLE_AVX)
|
||||
include(CheckAvxSupport)
|
||||
get_avx_compile_options(AVX_COMPILE_OPTIONS)
|
||||
else()
|
||||
set(AVX_COMPILE_OPTIONS)
|
||||
endif()
|
||||
|
||||
option(MUJOCO_BUILD_MACOS_FRAMEWORKS "Build libraries as macOS Frameworks" OFF)
|
||||
|
||||
# Get some extra link options.
|
||||
include(MujocoLinkOptions)
|
||||
get_mujoco_extra_link_options(EXTRA_LINK_OPTIONS)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC))
|
||||
set(EXTRA_COMPILE_OPTIONS -Wall -Werror)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(EXTRA_COMPILE_OPTIONS
|
||||
-Wno-int-in-bool-context
|
||||
-Wno-maybe-uninitialized
|
||||
-Wno-sign-compare
|
||||
-Wno-stringop-overflow
|
||||
-Wno-stringop-truncation
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include(MujocoHarden)
|
||||
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
||||
@@ -0,0 +1,188 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#[=======================================================================[.rst:
|
||||
TargetAddRpath
|
||||
----------------------
|
||||
|
||||
Add support to RPATH for the specified targets
|
||||
|
||||
.. command:: target_add_rpath
|
||||
|
||||
Add support to RPATH for the specified targets::
|
||||
|
||||
.. code-block:: cmake
|
||||
target_add_rpath(target1 target2 ...
|
||||
INSTALL_DIRECTORY install_directory
|
||||
LIB_DIRS dir1 dir2 ...
|
||||
[INSTALL_NAME_DIR [dir]]
|
||||
[DEPENDS condition [condition]]
|
||||
[USE_LINK_PATH])
|
||||
|
||||
This function setups the RPATH paths for the specified targets. The use of
|
||||
RPATH allows to avoid using the (dangerous) environment variable
|
||||
``LD_LIBRARY_PATH`` (or equivalent on macOS) when installing without absolute
|
||||
paths.
|
||||
By using RPATH the installation can be relocated as the linker will look for
|
||||
(some of) the dependencies at run time.
|
||||
|
||||
The function has the following parameters:
|
||||
|
||||
Options:
|
||||
- ``USE_LINK_PATH``: if defined, the function will set
|
||||
``INSTALL_RPATH_USE_LINK_PATH`` on all the specified targets, i.e. CMake
|
||||
will automatically adds to the RPATH the path to all the dependent
|
||||
libraries defined outside this project.
|
||||
|
||||
Arguments:
|
||||
- ``INSTALL_DIRECTORY`` The directory where the specified targets will be
|
||||
installed.
|
||||
- ``LIB_DIRS`` list of directories to be added a search path to the RPATH.
|
||||
Note that the relative path between ``INSTALL_DIRECTORY`` and these
|
||||
directories will be added to the RPATH.
|
||||
- ``INSTALL_NAME_DIR`` directory where the libraries will be installed.
|
||||
This variable will be used only if ``CMAKE_SKIP_RPATH`` or
|
||||
``CMAKE_SKIP_INSTALL_RPATH`` is set to ``TRUE`` as it will set the
|
||||
``INSTALL_NAME_DIR`` on all targets.
|
||||
- ``DEPENDS`` list of conditions that should be ``TRUE`` to enable
|
||||
RPATH, for example ``FOO; NOT BAR``.
|
||||
|
||||
Note: see https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
|
||||
and https://gitlab.kitware.com/cmake/cmake/issues/16589 for further details.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
if(COMMAND target_add_rpath)
|
||||
return()
|
||||
endif()
|
||||
|
||||
function(_get_system_dirs _output_var)
|
||||
set(${_output_var}
|
||||
${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(
|
||||
_get_rpath_relative_path
|
||||
_output_var
|
||||
_bin_dir
|
||||
_lib_dir
|
||||
)
|
||||
file(
|
||||
RELATIVE_PATH
|
||||
_rel_path
|
||||
${_bin_dir}
|
||||
${_lib_dir}
|
||||
)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(${_output_var}
|
||||
"@loader_path/${_rel_path}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
else()
|
||||
set(${_output_var}
|
||||
"\$ORIGIN/${_rel_path}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(target_add_rpath)
|
||||
set(_options USE_LINK_PATH)
|
||||
set(_oneValueArgs INSTALL_NAME_DIR INSTALL_DIRECTORY)
|
||||
set(_multiValueArgs TARGETS LIB_DIRS DEPENDS)
|
||||
|
||||
cmake_parse_arguments(
|
||||
_ARGS
|
||||
"${_options}"
|
||||
"${_oneValueArgs}"
|
||||
"${_multiValueArgs}"
|
||||
"${ARGN}"
|
||||
)
|
||||
|
||||
# Handle Apple-specific installation directory. Note that this disable proper RPATH.
|
||||
if(CMAKE_SKIP_RPATH OR CMAKE_SKIP_INSTALL_RPATH)
|
||||
if(DEFINED _ARGS_INSTALL_NAME_DIR)
|
||||
set_target_properties(${_ARGS_TARGETS} PROPERTIES INSTALL_NAME_DIR ${_ARGS_INSTALL_NAME_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If RPATH is disabled, do nothing and return.
|
||||
if(CMAKE_SKIP_RPATH OR (CMAKE_SKIP_INSTALL_RPATH AND CMAKE_SKIP_BUILD_RPATH))
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check if the user requested RPATH for the specified targets.
|
||||
set(_enable_rpath ON)
|
||||
if(DEFINED _ARGS_DEPENDS)
|
||||
foreach(_cond ${_ARGS_DEPENDS})
|
||||
string(
|
||||
REGEX
|
||||
REPLACE " +"
|
||||
";"
|
||||
_cond
|
||||
"${_cond}"
|
||||
)
|
||||
if(NOT (${_cond}))
|
||||
set(_enable_rpath OFF)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(NOT _enable_rpath)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Now enable RPATH for the specified targets.
|
||||
_get_system_dirs(_system_dirs)
|
||||
|
||||
# We do this per target to preserve the original rpath setting.
|
||||
foreach(_target ${_ARGS_TARGETS})
|
||||
get_target_property(_install_rpath ${_target} INSTALL_RPATH)
|
||||
|
||||
foreach(_lib_dir ${_ARGS_LIB_DIRS})
|
||||
# Check if the specified library path is a system directory. These are always searched so we do
|
||||
# not need to include them in the RPATH.
|
||||
list(
|
||||
FIND
|
||||
_system_dirs
|
||||
"${_lib_dir}"
|
||||
is_system_dir
|
||||
)
|
||||
if("${is_system_dir}" STREQUAL "-1")
|
||||
|
||||
_get_rpath_relative_path(_bin_lib_rel_path ${_ARGS_INSTALL_DIRECTORY} ${_lib_dir})
|
||||
list(APPEND _install_rpath ${_bin_lib_rel_path})
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT
|
||||
"${_install_rpath}"
|
||||
STREQUAL
|
||||
""
|
||||
)
|
||||
list(REMOVE_DUPLICATES _install_rpath)
|
||||
endif()
|
||||
|
||||
set_target_properties(
|
||||
${_target}
|
||||
PROPERTIES INSTALL_RPATH ${_install_rpath}
|
||||
INSTALL_RPATH_USE_LINK_PATH ${_ARGS_USE_LINK_PATH}
|
||||
MACOSX_RPATH ON # This is ON by default.
|
||||
)
|
||||
endforeach()
|
||||
|
||||
endfunction()
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Expecting an output directory. Got none." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "$1"
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(OpenGL)
|
||||
|
||||
if(NOT TARGET mujoco AND NOT @PROJECT_NAME@_BINARY_DIR)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/mujocoTargets.cmake")
|
||||
endif()
|
||||
|
||||
check_required_components(mujoco)
|
||||
@@ -0,0 +1,92 @@
|
||||
From 2bf2d1f5151d0d36cd17dea03129bd9a825384c5 Mon Sep 17 00:00:00 2001
|
||||
From: Francesco Romano <francesco.romano.1987@gmail.com>
|
||||
Date: Fri, 6 May 2022 11:30:44 +0100
|
||||
Subject: [PATCH] Add option to disable testing
|
||||
|
||||
---
|
||||
CMakeLists.txt | 55 ++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 29 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index cd95ad0..6ff1c98 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -113,6 +113,7 @@ cmake_dependent_option(LINK_APPS_SHARED "Use shared library for linking applicat
|
||||
"BUILD_SHARED_LIBS;BUILD_STATIC_LIBS"
|
||||
${BUILD_SHARED_LIBS}
|
||||
)
|
||||
+option(QHULL_ENABLE_TESTING "Build and run tests" ON)
|
||||
|
||||
if(INCLUDE_INSTALL_DIR)
|
||||
else()
|
||||
@@ -147,6 +148,7 @@ message(STATUS "Build Type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS "Build static libraries: ${BUILD_STATIC_LIBS}")
|
||||
message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}")
|
||||
message(STATUS "Use shared library for linking apps: ${LINK_APPS_SHARED}")
|
||||
+message(STATUS "Build tests: ${QHULL_ENABLE_TESTING}")
|
||||
message(STATUS "To override these options, add -D{OPTION_NAME}=... to the cmake command")
|
||||
message(STATUS " Build the debug targets -DCMAKE_BUILD_TYPE=Debug")
|
||||
message(STATUS)
|
||||
@@ -636,32 +638,33 @@ set_target_properties(user_egp PROPERTIES
|
||||
# ---------------------------------------
|
||||
# Define test
|
||||
# ---------------------------------------
|
||||
-
|
||||
-enable_testing()
|
||||
-add_test(NAME testqset
|
||||
- COMMAND ./testqset 10000)
|
||||
-add_test(NAME testqset_r
|
||||
- COMMAND ./testqset_r 10000)
|
||||
-add_test(NAME smoketest
|
||||
- COMMAND sh -c "./rbox D4 | ./qhull Tv")
|
||||
-add_test(NAME rbox-10-qhull
|
||||
- COMMAND sh -c "./rbox 10 | ./qhull Tv")
|
||||
-add_test(NAME rbox-10-qconvex
|
||||
- COMMAND sh -c "./rbox 10 | ./qconvex Tv")
|
||||
-add_test(NAME rbox-10-qdelaunay
|
||||
- COMMAND sh -c "./rbox 10 | ./qdelaunay Tv")
|
||||
-add_test(NAME rbox-10-qhalf
|
||||
- COMMAND sh -c "./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv")
|
||||
-add_test(NAME rbox-10-qvoronoi
|
||||
- COMMAND sh -c "./rbox 10 | ./qvoronoi Tv")
|
||||
-add_test(NAME user_eg
|
||||
- COMMAND sh -c "./user_eg")
|
||||
-add_test(NAME user_eg2
|
||||
- COMMAND sh -c "./user_eg2")
|
||||
-
|
||||
-if(${BUILD_STATIC_LIBS})
|
||||
- add_test(NAME user_eg3
|
||||
- COMMAND sh -c "./user_eg3 rbox '10 D2' '2 D2' qhull 's p' facets")
|
||||
+if (QHULL_ENABLE_TESTING)
|
||||
+ enable_testing()
|
||||
+ add_test(NAME testqset
|
||||
+ COMMAND ./testqset 10000)
|
||||
+ add_test(NAME testqset_r
|
||||
+ COMMAND ./testqset_r 10000)
|
||||
+ add_test(NAME smoketest
|
||||
+ COMMAND sh -c "./rbox D4 | ./qhull Tv")
|
||||
+ add_test(NAME rbox-10-qhull
|
||||
+ COMMAND sh -c "./rbox 10 | ./qhull Tv")
|
||||
+ add_test(NAME rbox-10-qconvex
|
||||
+ COMMAND sh -c "./rbox 10 | ./qconvex Tv")
|
||||
+ add_test(NAME rbox-10-qdelaunay
|
||||
+ COMMAND sh -c "./rbox 10 | ./qdelaunay Tv")
|
||||
+ add_test(NAME rbox-10-qhalf
|
||||
+ COMMAND sh -c "./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv")
|
||||
+ add_test(NAME rbox-10-qvoronoi
|
||||
+ COMMAND sh -c "./rbox 10 | ./qvoronoi Tv")
|
||||
+ add_test(NAME user_eg
|
||||
+ COMMAND sh -c "./user_eg")
|
||||
+ add_test(NAME user_eg2
|
||||
+ COMMAND sh -c "./user_eg2")
|
||||
+
|
||||
+ if(${BUILD_STATIC_LIBS})
|
||||
+ add_test(NAME user_eg3
|
||||
+ COMMAND sh -c "./user_eg3 rbox '10 D2' '2 D2' qhull 's p' facets")
|
||||
+ endif()
|
||||
endif()
|
||||
|
||||
# ---------------------------------------
|
||||
--
|
||||
2.36.0.512.ge40c2bad7a-goog
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Expecting an output directory. Got none." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$1"
|
||||
rm -rf "$1/*"
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>MuJoCo</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.mujoco.mujoco</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${PROJECT_VERSION}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${PROJECT_VERSION}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>libmujoco.dylib</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright 2021 DeepMind Technologies Limited.</string>
|
||||
<key>MDItemKeywords</key>
|
||||
<string>MuJoCo, physics engine, physics simulator, physics, MJ</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>simulate</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>MDItemKeywords</key>
|
||||
<string>MuJoCo, physics engine, physics simulator, physics, simulate, MJ, mujoco simulate, mj simulate</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "mujoco.ico"
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
framework module mujoco {
|
||||
umbrella header "mujoco.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
+81
-81
@@ -38,7 +38,7 @@ mjtNum
|
||||
typedef float mjtNum;
|
||||
#endif
|
||||
|
||||
| Defined in `mjtnum.h <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`_
|
||||
| Defined in `mjtnum.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`_
|
||||
|
||||
| This is the floating-point type used throughout the simulator. If the symbol ``mjUSEDOUBLE`` is defined in
|
||||
``mjmodel.h``, this type is defined as ``double``, otherwise it is defined as ``float``. Currently only the
|
||||
@@ -61,7 +61,7 @@ mjtByte
|
||||
|
||||
typedef unsigned char mjtByte;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Byte type used to represent boolean variables.
|
||||
|
||||
@@ -90,7 +90,7 @@ mjtDisableBit
|
||||
mjNDISABLE = 12 // number of disable flags
|
||||
} mjtDisableBit;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Constants which are powers of 2. They are used as bitmasks for the field ``disableflags`` of :ref:`mjOption`.
|
||||
At runtime this field is ``m->opt.disableflags``. The number of these constants is given by ``mjNDISABLE`` which is
|
||||
@@ -117,7 +117,7 @@ mjtEnableBit
|
||||
mjNENABLE = 5 // number of enable flags
|
||||
} mjtEnableBit;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Constants which are powers of 2. They are used as bitmasks for the field ``enableflags`` of :ref:`mjOption`.
|
||||
At runtime this field is ``m->opt.enableflags``. The number of these constants is given by ``mjNENABLE`` which is also
|
||||
@@ -138,7 +138,7 @@ mjtJoint
|
||||
mjJNT_HINGE // rotation angle (rad) around body-fixed axis (1)
|
||||
} mjtJoint;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Primitive joint types. These values are used in ``m->jnt_type``. The numbers in the comments indicate how many
|
||||
positional coordinates each joint type has. Note that ball joints and rotational components of free joints are
|
||||
@@ -176,7 +176,7 @@ mjtGeom
|
||||
mjGEOM_NONE = 1001 // missing geom type
|
||||
} mjtGeom;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Geometric types supported by MuJoCo. The first group are "official" geom types that can be used in the model. The
|
||||
second group are geom types that cannot be used in the model but are used by the visualizer to add decorative
|
||||
@@ -198,7 +198,7 @@ mjtCamLight
|
||||
mjCAMLIGHT_TARGETBODYCOM // pos fixed in body, rot tracks target subtree com
|
||||
} mjtCamLight;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Dynamic modes for cameras and lights, specifying how the camera/light position and orientation are computed. These
|
||||
values are used in ``m->cam_mode`` and ``m->light_mode``.
|
||||
@@ -217,7 +217,7 @@ mjtTexture
|
||||
mjTEXTURE_SKYBOX // cube texture used as skybox
|
||||
} mjtTexture;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Texture types, specifying how the texture will be mapped. These values are used in ``m->tex_type``.
|
||||
|
||||
@@ -234,7 +234,7 @@ mjtIntegrator
|
||||
mjINT_RK4 // 4th-order Runge Kutta
|
||||
} mjtIntegrator;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Numerical integrator types. These values are used in ``m->opt.integrator``.
|
||||
|
||||
@@ -252,7 +252,7 @@ mjtCollision
|
||||
mjCOL_DYNAMIC // test dynamic pairs only
|
||||
} mjtCollision;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Collision modes specifying how candidate geom pairs are generated for near-phase collision checking. These values are
|
||||
used in ``m->opt.collision``.
|
||||
@@ -270,7 +270,7 @@ mjtCone
|
||||
mjCONE_ELLIPTIC // elliptic
|
||||
} mjtCone;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Available friction cone types. These values are used in ``m->opt.cone``.
|
||||
|
||||
@@ -288,7 +288,7 @@ mjtJacobian
|
||||
mjJAC_AUTO // dense if nv<=60, sparse otherwise
|
||||
} mjtJacobian;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Available Jacobian types. These values are used in ``m->opt.jacobian``.
|
||||
|
||||
@@ -306,7 +306,7 @@ mjtSolver
|
||||
mjSOL_NEWTON // Newton (primal)
|
||||
} mjtSolver;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Available constraint solver algorithms. These values are used in ``m->opt.solver``.
|
||||
|
||||
@@ -326,7 +326,7 @@ mjtEq
|
||||
mjEQ_DISTANCE // fix the contact distance betweent two geoms
|
||||
} mjtEq;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Equality constraint types. These values are used in ``m->eq_type``.
|
||||
|
||||
@@ -347,7 +347,7 @@ mjtWrap
|
||||
mjWRAP_CYLINDER // wrap around (infinite) cylinder
|
||||
} mjtWrap;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Tendon wrapping object types. These values are used in ``m->wrap_type``.
|
||||
|
||||
@@ -369,7 +369,7 @@ mjtTrn
|
||||
mjTRN_UNDEFINED = 1000 // undefined transmission type
|
||||
} mjtTrn;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Actuator transmission types. These values are used in ``m->actuator_trntype``.
|
||||
|
||||
@@ -389,7 +389,7 @@ mjtDyn
|
||||
mjDYN_USER // user-defined dynamics type
|
||||
} mjtDyn;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Actuator dynamics types. These values are used in ``m->actuator_dyntype``.
|
||||
|
||||
@@ -407,7 +407,7 @@ mjtGain
|
||||
mjGAIN_USER // user-defined gain type
|
||||
} mjtGain;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Actuator gain types. These values are used in ``m->actuator_gaintype``.
|
||||
|
||||
@@ -426,7 +426,7 @@ mjtBias
|
||||
mjBIAS_USER // user-defined bias type
|
||||
} mjtBias;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Actuator bias types. These values are used in ``m->actuator_biastype``.
|
||||
|
||||
@@ -465,7 +465,7 @@ mjtObj
|
||||
mjOBJ_KEY // keyframe
|
||||
} mjtObj;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| MuJoCo object types. These values are used in the support functions :ref:`mj_name2id` and
|
||||
:ref:`mj_id2name` to convert between object names and integer ids.
|
||||
@@ -489,7 +489,7 @@ mjtConstraint
|
||||
mjCNSTR_CONTACT_ELLIPTIC // frictional contact, elliptic friction cone
|
||||
} mjtConstraint;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Constraint types. These values are not used in mjModel, but are used in the mjData field ``d->efc_type`` when the list
|
||||
of active constraints is constructed at each simulation time step.
|
||||
@@ -510,7 +510,7 @@ mjtConstraintState
|
||||
mjCNSTRSTATE_CONE // squared distance to cone cost (elliptic contact)
|
||||
} mjtConstraintState;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| These values are used by the solver internally to keep track of the constraint states.
|
||||
|
||||
@@ -574,7 +574,7 @@ mjtSensor
|
||||
mjSENS_USER // sensor data provided by mjcb_sensor callback
|
||||
} mjtSensor;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| Sensor types. These values are used in ``m->sensor_type``.
|
||||
|
||||
@@ -593,7 +593,7 @@ mjtStage
|
||||
mjSTAGE_ACC // acceleration/force-dependent computations
|
||||
} mjtStage;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| These are the compute stages for the skipstage parameters of :ref:`mj_forwardSkip` and
|
||||
:ref:`mj_inverseSkip`.
|
||||
@@ -613,7 +613,7 @@ mjtDataType
|
||||
mjDATATYPE_QUATERNION // unit quaternion
|
||||
} mjtDataType;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| These are the possible sensor data types, used in ``mjData.sensor_datatype``.
|
||||
|
||||
@@ -638,7 +638,7 @@ mjtWarning
|
||||
mjNWARNING // number of warnings
|
||||
} mjtWarning;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| Warning types. The number of warning types is given by ``mjNWARNING`` which is also the length of the array
|
||||
``mjData.warning``.
|
||||
@@ -674,7 +674,7 @@ mjtTimer
|
||||
mjNTIMER // number of timers
|
||||
} mjtTimer;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| Timer types. The number of timer types is given by ``mjNTIMER`` which is also the length of the array
|
||||
``mjData.timer``, as well as the length of the string array :ref:`mjTIMERSTRING` with timer names.
|
||||
@@ -694,7 +694,7 @@ mjtCatBit
|
||||
mjCAT_ALL = 7 // select all categories
|
||||
} mjtCatBit;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the available categories of geoms in the abstract visualizer. The bitmask can be used in the function
|
||||
:ref:`mjr_render` to specify which categories should be rendered.
|
||||
@@ -717,7 +717,7 @@ mjtMouse
|
||||
mjMOUSE_SELECT // selection
|
||||
} mjtMouse;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the mouse actions that the abstract visualizer recognizes. It is up to the user to intercept mouse events
|
||||
and translate them into these actions, as illustrated in ``simulate.cc``.
|
||||
@@ -735,7 +735,7 @@ mjtPertBit
|
||||
mjPERT_ROTATE = 2 // rotation
|
||||
} mjtPertBit;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These bitmasks enable the translational and rotational components of the mouse perturbation. For the regular mouse,
|
||||
only one can be enabled at a time. For the 3D mouse (SpaceNavigator) both can be enabled simultaneously. They are used
|
||||
@@ -756,7 +756,7 @@ mjtCamera
|
||||
mjCAMERA_USER // user is responsible for setting OpenGL camera
|
||||
} mjtCamera;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the possible camera types, used in ``mjvCamera.type``.
|
||||
|
||||
@@ -787,7 +787,7 @@ mjtLabel
|
||||
mjNLABEL // number of label types
|
||||
} mjtLabel;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the abstract visualization elements that can have text labels. Used in ``mjvOption.label``.
|
||||
|
||||
@@ -811,7 +811,7 @@ mjtFrame
|
||||
mjNFRAME // number of visualization frames
|
||||
} mjtFrame;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the MuJoCo objects whose spatial frames can be rendered. Used in ``mjvOption.frame``.
|
||||
|
||||
@@ -850,7 +850,7 @@ mjtVisFlag
|
||||
mjNVISFLAG // number of visualization flags
|
||||
} mjtVisFlag;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are indices in the array ``mjvOption.flags``, whose elements enable/disable the visualization of the
|
||||
corresponding model or decoration element.
|
||||
@@ -877,7 +877,7 @@ mjtRndFlag
|
||||
mjNRNDFLAG // number of rendering flags
|
||||
} mjtRndFlag;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are indices in the array ``mjvScene.flags``, whose elements enable/disable OpenGL rendering effects.
|
||||
|
||||
@@ -895,7 +895,7 @@ mjtStereo
|
||||
mjSTEREO_SIDEBYSIDE // side-by-side
|
||||
} mjtStereo;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| These are the possible stereo rendering types. They are used in ``mjvScene.stereo``.
|
||||
|
||||
@@ -914,7 +914,7 @@ mjtGridPos
|
||||
mjGRID_BOTTOMRIGHT // bottom right
|
||||
} mjtGridPos;
|
||||
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_
|
||||
|
||||
| These are the possible grid positions for text overlays. They are used as an argument to the function
|
||||
:ref:`mjr_overlay`.
|
||||
@@ -932,7 +932,7 @@ mjtFramebuffer
|
||||
mjFB_OFFSCREEN // offscreen buffer
|
||||
} mjtFramebuffer;
|
||||
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_
|
||||
|
||||
| These are the possible framebuffers. They are used as an argument to the function :ref:`mjr_setBuffer`.
|
||||
|
||||
@@ -953,7 +953,7 @@ mjtFontScale
|
||||
mjFONTSCALE_300 = 300 // 300% scale
|
||||
} mjtFontScale;
|
||||
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_
|
||||
|
||||
| These are the possible font sizes. The fonts are predefined bitmaps stored in the dynamic library at three different
|
||||
sizes.
|
||||
@@ -972,7 +972,7 @@ mjtFont
|
||||
mjFONT_BIG // big font (for user alerts)
|
||||
} mjtFont;
|
||||
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
|
||||
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_
|
||||
|
||||
| These are the possible font types.
|
||||
|
||||
@@ -991,7 +991,7 @@ mjtButton
|
||||
mjBUTTON_MIDDLE // middle button
|
||||
} mjtButton;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| Mouse button IDs used in the UI framework.
|
||||
|
||||
@@ -1013,7 +1013,7 @@ mjtEvent
|
||||
mjEVENT_RESIZE // resize
|
||||
} mjtEvent;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| Event types used in the UI framework.
|
||||
|
||||
@@ -1046,7 +1046,7 @@ mjtItem
|
||||
mjNITEM // number of item types
|
||||
} mjtItem;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| Item types used in the UI framework.
|
||||
|
||||
@@ -1055,8 +1055,8 @@ mjtItem
|
||||
Function types
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
MuJoCo callbacks have corresponding function types. They are defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_ and in
|
||||
`mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_. The actual callback functions are documented later.
|
||||
MuJoCo callbacks have corresponding function types. They are defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_ and in
|
||||
`mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_. The actual callback functions are documented later.
|
||||
|
||||
.. _mjfGeneric:
|
||||
|
||||
@@ -1163,7 +1163,7 @@ mjVFS
|
||||
};
|
||||
typedef struct _mjVFS mjVFS;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| This is the data structure with the virtual file system. It can only be constructed programmatically, and does not
|
||||
have an analog in MJCF.
|
||||
@@ -1213,7 +1213,7 @@ mjOption
|
||||
};
|
||||
typedef struct _mjOption mjOption;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| This is the data structure with simulation options. It corresponds to the MJCF element
|
||||
:ref:`option <option>`. One instance of it is embedded in mjModel.
|
||||
@@ -1319,7 +1319,7 @@ mjVisual
|
||||
};
|
||||
typedef struct _mjVisual mjVisual;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| This is the data structure with abstract visualization options. It corresponds to the MJCF element
|
||||
:ref:`visual <visual>`. One instance of it is embedded in mjModel.
|
||||
@@ -1341,7 +1341,7 @@ mjStatistic
|
||||
};
|
||||
typedef struct _mjStatistic mjStatistic;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| This is the data structure with model statistics precomputed by the compiler or set by the user. It corresponds to the
|
||||
MJCF element :ref:`statistic <statistic>`. One instance of it is embedded in mjModel.
|
||||
@@ -1751,7 +1751,7 @@ mjModel
|
||||
};
|
||||
typedef struct _mjModel mjModel;
|
||||
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
|
||||
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_
|
||||
|
||||
| This is the main data structure holding the MuJoCo model. It is treated as constant by the simulator.
|
||||
|
||||
@@ -1792,7 +1792,7 @@ mjContact
|
||||
};
|
||||
typedef struct _mjContact mjContact;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| This is the data structure holding information about one contact. ``mjData.contact`` is a preallocated array of
|
||||
mjContact data structures, populated at runtime with the contacts found by the collision detector. Additional contact
|
||||
@@ -1812,7 +1812,7 @@ mjWarningStat
|
||||
};
|
||||
typedef struct _mjWarningStat mjWarningStat;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| This is the data structure holding information about one warning type. ``mjData.warning`` is a preallocated array of
|
||||
mjWarningStat data structures, one for each warning type.
|
||||
@@ -1831,7 +1831,7 @@ mjTimerStat
|
||||
};
|
||||
typedef struct _mjTimerStat mjTimerStat;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| This is the data structure holding information about one timer. ``mjData.timer`` is a preallocated array of
|
||||
mjTimerStat data structures, one for each timer type.
|
||||
@@ -1855,7 +1855,7 @@ mjSolverStat
|
||||
};
|
||||
typedef struct _mjSolverStat mjSolverStat;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| This is the data structure holding information about one solver iteration. ``mjData.solver`` is a preallocated array
|
||||
of mjSolverStat data structures, one for each iteration of the solver, up to a maximum of mjNSOLVER. The actual number
|
||||
@@ -2042,11 +2042,11 @@ mjData
|
||||
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||
|
||||
// computed by mj_fwdAcceleration
|
||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
||||
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_smooth; // unconstrained acceleration (nv x 1)
|
||||
|
||||
// computed by mj_fwdConstraint/mj_inverse
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (njmax x 1)
|
||||
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||
@@ -2062,7 +2062,7 @@ mjData
|
||||
};
|
||||
typedef struct _mjData mjData;
|
||||
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
|
||||
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_
|
||||
|
||||
| This is the main data structure holding the simulation state. It is the workspace where all functions read their
|
||||
modifiable inputs and write their outputs.
|
||||
@@ -2086,7 +2086,7 @@ mjvPerturb
|
||||
};
|
||||
typedef struct _mjvPerturb mjvPerturb;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This is the data structure holding information about mouse perturbations.
|
||||
|
||||
@@ -2112,7 +2112,7 @@ mjvCamera
|
||||
};
|
||||
typedef struct _mjvCamera mjvCamera;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This is the data structure describing one abstract camera.
|
||||
|
||||
@@ -2139,7 +2139,7 @@ mjvGLCamera
|
||||
};
|
||||
typedef struct _mjvGLCamera mjvGLCamera;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This is the data structure describing one OpenGL camera.
|
||||
|
||||
@@ -2182,7 +2182,7 @@ mjvGeom
|
||||
};
|
||||
typedef struct _mjvGeom mjvGeom;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This is the data structure describing one abstract visualization geom - which could correspond to a model geom or to a
|
||||
decoration element constructed by the visualizer.
|
||||
@@ -2210,7 +2210,7 @@ mjvLight
|
||||
};
|
||||
typedef struct _mjvLight mjvLight;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This is the data structure describing one OpenGL light.
|
||||
|
||||
@@ -2234,7 +2234,7 @@ mjvOption
|
||||
};
|
||||
typedef struct _mjvOption mjvOption;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This structure contains options that enable and disable the visualization of various elements.
|
||||
|
||||
@@ -2280,7 +2280,7 @@ mjvScene
|
||||
};
|
||||
typedef struct _mjvScene mjvScene;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This structure contains everything needed to render the 3D scene in OpenGL.
|
||||
|
||||
@@ -2334,7 +2334,7 @@ mjvFigure
|
||||
};
|
||||
typedef struct _mjvFigure mjvFigure;
|
||||
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
|
||||
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_
|
||||
|
||||
| This structure contains everything needed to render a 2D plot in OpenGL. The buffers for line points etc. are
|
||||
preallocated, and the user has to populate them before calling the function :ref:`mjr_figure` with this
|
||||
@@ -2356,7 +2356,7 @@ mjrRect
|
||||
};
|
||||
typedef struct _mjrRect mjrRect;
|
||||
|
||||
| Defined in `mjrender.h (57) <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h#L57>`_
|
||||
| Defined in `mjrender.h (57) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h#L57>`_
|
||||
|
||||
| This structure specifies a rectangle.
|
||||
|
||||
@@ -2451,7 +2451,7 @@ mjrContext
|
||||
};
|
||||
typedef struct _mjrContext mjrContext;
|
||||
|
||||
| Defined in `mjrender.h (67) <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h#L67>`_
|
||||
| Defined in `mjrender.h (67) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h#L67>`_
|
||||
|
||||
| This structure contains the custom OpenGL rendering context, with the ids of all OpenGL resources uploaded to the GPU.
|
||||
|
||||
@@ -2502,7 +2502,7 @@ mjuiState
|
||||
};
|
||||
typedef struct _mjuiState mjuiState;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure contains the keyboard and mouse state used by the UI framework.
|
||||
|
||||
@@ -2529,7 +2529,7 @@ mjuiThemeSpacing
|
||||
};
|
||||
typedef struct _mjuiThemeSpacing mjuiThemeSpacing;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines the spacing of UI items in the theme.
|
||||
|
||||
@@ -2566,7 +2566,7 @@ mjuiThemeColor
|
||||
};
|
||||
typedef struct _mjuiThemeColor mjuiThemeColor;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines the colors of UI items in the theme.
|
||||
|
||||
@@ -2624,7 +2624,7 @@ mjuiItem
|
||||
};
|
||||
typedef struct _mjuiItem mjuiItem;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines one UI item.
|
||||
|
||||
@@ -2651,7 +2651,7 @@ mjuiSection
|
||||
};
|
||||
typedef struct _mjuiSection mjuiSection;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines one section of the UI.
|
||||
|
||||
@@ -2698,7 +2698,7 @@ mjUI
|
||||
};
|
||||
typedef struct _mjUI mjUI;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines the entire UI.
|
||||
|
||||
@@ -2719,7 +2719,7 @@ mjuiDef
|
||||
};
|
||||
typedef struct _mjuiDef mjuiDef;
|
||||
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
|
||||
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_
|
||||
|
||||
| This structure defines one entry in the definition table used for simplified UI construction.
|
||||
|
||||
@@ -2730,7 +2730,7 @@ X Macros
|
||||
|
||||
The X Macros are not needed in most user projects. They are used internally to allocate the model, and are also
|
||||
available for users who know how to use this programming technique. See the header file
|
||||
`mjxmacro.h <https://github.com/deepmind/mujoco/blob/main/include/mjxmacro.h>`_ for the actual definitions. They are particularly useful in writing MuJoCo wrappers
|
||||
`mjxmacro.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`_ for the actual definitions. They are particularly useful in writing MuJoCo wrappers
|
||||
for scripting languages, where dynamic structures matching the MuJoCo data structures need to be constructed
|
||||
programmatically.
|
||||
|
||||
@@ -3231,7 +3231,7 @@ Numeric constants
|
||||
API functions
|
||||
-------------
|
||||
|
||||
The main header `mujoco.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco.h>`_ exposes a very large number
|
||||
The main header `mujoco.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mujoco.h>`_ exposes a very large number
|
||||
of functions. However the functions that most users are likely to need are a small fraction. For example,
|
||||
``simulate.cc`` which is as elaborate as a MuJoCo application is likely to get, calls around 40 of these functions,
|
||||
while ``basic.cc`` calls around 20. The rest are explosed just in case someone has a use for them. This includes us as
|
||||
@@ -3852,7 +3852,7 @@ mj_fwdActuation
|
||||
|
||||
void mj_fwdActuation(const mjModel* m, mjData* d);
|
||||
|
||||
Compute actuator force qfrc_actuation.
|
||||
Compute actuator force qfrc_actuator.
|
||||
|
||||
.. _mj_fwdAcceleration:
|
||||
|
||||
@@ -3863,7 +3863,7 @@ mj_fwdAcceleration
|
||||
|
||||
void mj_fwdAcceleration(const mjModel* m, mjData* d);
|
||||
|
||||
Add up all non-constraint forces, compute qacc_unc.
|
||||
Add up all non-constraint forces, compute qacc_smooth.
|
||||
|
||||
.. _mj_fwdConstraint:
|
||||
|
||||
@@ -6118,7 +6118,7 @@ mju_mulQuat
|
||||
|
||||
void mju_mulQuat(mjtNum res[4], const mjtNum quat1[4], const mjtNum quat2[4]);
|
||||
|
||||
Muiltiply quaternions.
|
||||
Multiply quaternions.
|
||||
|
||||
.. _mju_mulQuatAxis:
|
||||
|
||||
@@ -6129,7 +6129,7 @@ mju_mulQuatAxis
|
||||
|
||||
void mju_mulQuatAxis(mjtNum res[4], const mjtNum quat[4], const mjtNum axis[3]);
|
||||
|
||||
Muiltiply quaternion and axis.
|
||||
Multiply quaternion and axis.
|
||||
|
||||
.. _mju_axisAngle2Quat:
|
||||
|
||||
|
||||
+130
-116
@@ -12,10 +12,10 @@ This chapter is the reference manual for the MJCF modeling language used in MuJo
|
||||
XML schema
|
||||
~~~~~~~~~~
|
||||
|
||||
| The table below summarizes the XML elements and their attributes in MJCF. It is generated automatically with the
|
||||
function :ref:`mj_printSchema` which prints out the custom schema used by the parser to validate the model file.
|
||||
Note that all information in MJCF is entered through elements and attributes. Text content in elements is not used;
|
||||
if present, the parser ignores it. The symbols in the second column of the table have the following meaning:
|
||||
The table below summarizes the XML elements and their attributes in MJCF. It is generated automatically with the
|
||||
function :ref:`mj_printSchema` which prints out the custom schema used by the parser to validate the model file.
|
||||
Note that all information in MJCF is entered through elements and attributes. Text content in elements is not used;
|
||||
if present, the parser ignores it. The symbols in the second column of the table have the following meaning:
|
||||
|
||||
====== ===================================================
|
||||
**!** required element, can appear only once
|
||||
@@ -24,8 +24,6 @@ XML schema
|
||||
**R** optional element, can appear many times recursively
|
||||
====== ===================================================
|
||||
|
||||
|
|
||||
|
||||
+--------------------------+----+------------------------------------------------------------------------------------+
|
||||
| :el:`mujoco` | ! | .. table:: |
|
||||
| | | :class: mjcf-attributes |
|
||||
@@ -355,15 +353,17 @@ XML schema
|
||||
| | | :class: mjcf-attributes |
|
||||
| | | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`ctrllimited` | :at:`forcelimited` | :at:`ctrlrange` | |
|
||||
| | | | :at:`ctrllimited` | :at:`forcelimited` | :at:`actlimited` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`forcerange` | :at:`gear` | :at:`cranklength` | |
|
||||
| | | | :at:`ctrlrange` | :at:`forcerange` | :at:`actrange` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`user` | :at:`group` | :at:`dyntype` | |
|
||||
| | | | :at:`gear` | :at:`cranklength` | | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`gaintype` | :at:`biastype` | :at:`dynprm` | |
|
||||
| | | | :at:`user` | :at:`group` | | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`gainprm` | :at:`biasprm` | | |
|
||||
| | | | :at:`dyntype` | :at:`gaintype` | :at:`biastype` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`dynprm` | :at:`gainprm` | :at:`biasprm` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
+--------------------------+----+------------------------------------------------------------------------------------+
|
||||
| |_2|:el:`motor` | ? | .. table:: |
|
||||
@@ -891,19 +891,21 @@ XML schema
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`name` | :at:`class` | :at:`group` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`ctrllimited` | :at:`forcelimited` | :at:`ctrlrange` | |
|
||||
| | | | :at:`ctrllimited` | :at:`forcelimited` | :at:`actlimited` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`forcerange` | :at:`lengthrange` | :at:`gear` | |
|
||||
| | | | :at:`ctrlrange` | :at:`forcerange` | :at:`actrange` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`cranklength` | :at:`user` | :at:`joint` | |
|
||||
| | | | :at:`joint` | :at:`tendon` | :at:`site` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`jointinparent` | :at:`tendon` | :at:`slidersite` | |
|
||||
| | | | :at:`lengthrange` | :at:`gear` | :at:`jointinparent` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`cranksite` | :at:`site` | :at:`dyntype` | |
|
||||
| | | | :at:`cranklength` | :at:`cranksite` | :at:`slidersite` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`gaintype` | :at:`biastype` | :at:`dynprm` | |
|
||||
| | | | :at:`user` | | | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`gainprm` | :at:`biasprm` | | |
|
||||
| | | | :at:`dyntype` | :at:`gaintype` | :at:`biastype` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
| | | | :at:`dynprm` | :at:`gainprm` | :at:`biasprm` | |
|
||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||
+--------------------------+----+------------------------------------------------------------------------------------+
|
||||
| |_2|:el:`motor` | \* | .. table:: |
|
||||
@@ -1913,7 +1915,7 @@ possibly slower speed. Note that `simulate.cc <https://github.com/deepmind/mujoc
|
||||
displays the frames per second (FPS). The target FPS is 60 Hz; if the number shown in the visualizer is substantially
|
||||
lower, this means that the GPU is over-loaded and the visualization should somehow be simplified.
|
||||
|
||||
:at:`shadowsize`: :at-val:`int, "1024"`
|
||||
:at:`shadowsize`: :at-val:`int, "4096"`
|
||||
This attribute specifies the size of the square texture used for shadow mapping. Higher values result is smoother
|
||||
shadows. The size of the area over which a :ref:`light <light>` can cast shadows also affects smoothness, so these
|
||||
settings should be adjusted jointly. The default here is somewhat conservative. Most modern GPUs are able to handle
|
||||
@@ -2743,39 +2745,42 @@ practice this is rarely needed.
|
||||
:el-prefix:`asset/` **skin** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| Skinned meshes (or skins) were added in MuJoCo 2.0. These are deformable meshes whose vertex positions and normals are
|
||||
computed each time the model is rendered. MuJoCo skins are only used for visualization and do not affect the physics
|
||||
in any way. In particular, collisions involve the geoms of the bodies to which the skin is attached, and not the skin
|
||||
itself. Unlike regular meshes which are referenced from geoms and participate in collisions, the skin is not
|
||||
referenced from anywhere else in the model. It is a stand-alone asset that is used by renderer and not by the
|
||||
simulator.
|
||||
| The skin has vertex positions and normals updated at runtime, and triangle faces and optional texture coordinates
|
||||
which are predefined. It also has "bones" used for updating. Bones are regular MuJoCo bodies referenced with the
|
||||
:el:`bone` subelement. Each bone has a list of vertex indices and corresponding real-valued weights which specify how
|
||||
much the bone position and orientation influence the corresponding vertex. The vertex has local coordinates with
|
||||
respect to every bone that influences it. The local coordinates are computed by the model compiler, given global
|
||||
vertex coordinates and global bind poses for each body. The bind poses do not have to correspond to the model
|
||||
reference configuration qpos0. Note that the vertex positions and bone bind poses provided in the skin definition are
|
||||
always global, even if the model itself is defined in local coordinates.
|
||||
| At runtime the local coordinates of each vertex with respect to each bone that influences it are converted to global
|
||||
coordinates, and averaged in proportion to the corresponding weights to obtain a single set of 3D coordinates for each
|
||||
vertex. Normals then are computed automatically given the resulting global vertex positions and face information.
|
||||
Finally, the skin can be inflated by applying an offset to each vertex position along its (computed) normal.
|
||||
| Skins are one-sided for rendering purposes; this is because back-face culling is needed to avoid shading and aliasing
|
||||
artifacts. When the skin is a closed 3D shape this does not matter because the back sides cannot be seen. But if the
|
||||
skin is a 2D object, we have to specify both sides and offset them slightly to avoid artifacts. Note that the
|
||||
composite objects introduced in MuJoCo 2.0 generate skins automatically. So one can save an XML model with a composite
|
||||
object, and obtain an elaborate example of how a skin is specified in the XML.
|
||||
| Similar to meshes, skins can be specified directly in the XML via attributes documented later, or loaded from a binary
|
||||
SKN file which is in a custom format. The specification of skins is more complex than meshes because of the bone
|
||||
subelements. The file format starts with a header of 4 integers: nvertex, ntexcoord, nface, nbone. The first three are
|
||||
the same as in meshes, and specify the total number of vertices, texture coordinate pairs, and triangle faces in the
|
||||
skin. ntexcoord can be zero or equal to nvertex. nbone specifies the number of MuJoCo bodies that will be used as
|
||||
bones in the skin. The header is followed by the vertex, texcoord and face data, followed by a specification for each
|
||||
bone. The bone specification contains the name of the corresponding model body, 3D bind position, 4D bind quaterion,
|
||||
number of vertices influenced by the bone, and the vertex index array and weight array. Body names are represented as
|
||||
fixed-length character arrays and are expected to be 0-terminated. Characters after the first 0 are ignored. The
|
||||
contents of the SKN file are:
|
||||
Skinned meshes (or skins) were added in MuJoCo 2.0. These are deformable meshes whose vertex positions and normals are
|
||||
computed each time the model is rendered. MuJoCo skins are only used for visualization and do not affect the physics
|
||||
in any way. In particular, collisions involve the geoms of the bodies to which the skin is attached, and not the skin
|
||||
itself. Unlike regular meshes which are referenced from geoms and participate in collisions, the skin is not
|
||||
referenced from anywhere else in the model. It is a stand-alone asset that is used by renderer and not by the
|
||||
simulator.
|
||||
|
||||
The skin has vertex positions and normals updated at runtime, and triangle faces and optional texture coordinates
|
||||
which are predefined. It also has "bones" used for updating. Bones are regular MuJoCo bodies referenced with the
|
||||
:el:`bone` subelement. Each bone has a list of vertex indices and corresponding real-valued weights which specify how
|
||||
much the bone position and orientation influence the corresponding vertex. The vertex has local coordinates with
|
||||
respect to every bone that influences it. The local coordinates are computed by the model compiler, given global
|
||||
vertex coordinates and global bind poses for each body. The bind poses do not have to correspond to the model
|
||||
reference configuration qpos0. Note that the vertex positions and bone bind poses provided in the skin definition are
|
||||
always global, even if the model itself is defined in local coordinates.
|
||||
|
||||
At runtime the local coordinates of each vertex with respect to each bone that influences it are converted to global
|
||||
coordinates, and averaged in proportion to the corresponding weights to obtain a single set of 3D coordinates for each
|
||||
vertex. Normals then are computed automatically given the resulting global vertex positions and face information.
|
||||
Finally, the skin can be inflated by applying an offset to each vertex position along its (computed) normal.
|
||||
Skins are one-sided for rendering purposes; this is because back-face culling is needed to avoid shading and aliasing
|
||||
artifacts. When the skin is a closed 3D shape this does not matter because the back sides cannot be seen. But if the
|
||||
skin is a 2D object, we have to specify both sides and offset them slightly to avoid artifacts. Note that the
|
||||
composite objects introduced in MuJoCo 2.0 generate skins automatically. So one can save an XML model with a composite
|
||||
object, and obtain an elaborate example of how a skin is specified in the XML.
|
||||
|
||||
Similar to meshes, skins can be specified directly in the XML via attributes documented later, or loaded from a binary
|
||||
SKN file which is in a custom format. The specification of skins is more complex than meshes because of the bone
|
||||
subelements. The file format starts with a header of 4 integers: nvertex, ntexcoord, nface, nbone. The first three are
|
||||
the same as in meshes, and specify the total number of vertices, texture coordinate pairs, and triangle faces in the
|
||||
skin. ntexcoord can be zero or equal to nvertex. nbone specifies the number of MuJoCo bodies that will be used as
|
||||
bones in the skin. The header is followed by the vertex, texcoord and face data, followed by a specification for each
|
||||
bone. The bone specification contains the name of the corresponding model body, 3D bind position, 4D bind quaterion,
|
||||
number of vertices influenced by the bone, and the vertex index array and weight array. Body names are represented as
|
||||
fixed-length character arrays and are expected to be 0-terminated. Characters after the first 0 are ignored. The
|
||||
contents of the SKN file are:
|
||||
|
||||
.. code:: Text
|
||||
|
||||
@@ -3030,7 +3035,7 @@ unit quaternions.
|
||||
|
||||
The **hinge** type creates a hinge joint with one rotational degree of freedom. The rotation takes place around a
|
||||
specified axis through a specified position. This is the most common type of joint and is therefore the default. Most
|
||||
models contact only hinge and free joints.
|
||||
models contain only hinge and free joints.
|
||||
:at:`group`: :at-val:`int, "0"`
|
||||
Integer group to which the joint belongs. This attribute can be used for custom tags. It is also used by the
|
||||
visualizer to enable and disable the rendering of entire groups of joints.
|
||||
@@ -3121,18 +3126,19 @@ mjModel. If the XML model is saved, it will appear as a regular joint of type "f
|
||||
:el-prefix:`body/` **geom** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This element creates a geom, and attaches it rigidly to the body within which the geom is defined. Multiple geoms can
|
||||
be attached to the same body. At runtime they determine the appearance and collision properties of the body. At
|
||||
compile time they can also determine the inertial properties of the body, depending on the presence of the
|
||||
:ref:`inertial <inertial>` element and the setting of the inertiafromgeom attribute of :ref:`compiler <compiler>`.
|
||||
This is done by summing the masses and inertias of all geoms attached to the body with geom group in the range
|
||||
specified by the inertiagrouprange attribute of :ref:`compiler <compiler>`. The geom masses and inertias are computed
|
||||
using the geom shape, a specified density or a geom mass which implies a density, and the assumption of uniform
|
||||
density.
|
||||
| Geoms are not strictly required for physics simulation. One can create and simulate a model that only has bodies and
|
||||
joints. Such a model can even be visualized, using equivalent inertia boxes to represent bodies. Only contact forces
|
||||
would be missing from such a simulation. We do not recommend using such models, but knowing that this is possible
|
||||
helps clarify the role of bodies and geoms in MuJoCo.
|
||||
This element creates a geom, and attaches it rigidly to the body within which the geom is defined. Multiple geoms can
|
||||
be attached to the same body. At runtime they determine the appearance and collision properties of the body. At
|
||||
compile time they can also determine the inertial properties of the body, depending on the presence of the
|
||||
:ref:`inertial <inertial>` element and the setting of the inertiafromgeom attribute of :ref:`compiler <compiler>`.
|
||||
This is done by summing the masses and inertias of all geoms attached to the body with geom group in the range
|
||||
specified by the inertiagrouprange attribute of :ref:`compiler <compiler>`. The geom masses and inertias are computed
|
||||
using the geom shape, a specified density or a geom mass which implies a density, and the assumption of uniform
|
||||
density.
|
||||
|
||||
Geoms are not strictly required for physics simulation. One can create and simulate a model that only has bodies and
|
||||
joints. Such a model can even be visualized, using equivalent inertia boxes to represent bodies. Only contact forces
|
||||
would be missing from such a simulation. We do not recommend using such models, but knowing that this is possible
|
||||
helps clarify the role of bodies and geoms in MuJoCo.
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the geom.
|
||||
@@ -3978,19 +3984,19 @@ can also represent different forms of mechanical coupling.
|
||||
:width: 400px
|
||||
:align: right
|
||||
|
||||
| This element creates a spatial tendon, which is a minimum-length path passing through specified via-points and
|
||||
wrapping around specified obstacle geoms. The objects along the path are defined with the sub-elements
|
||||
:ref:`site <spatial-site>` and :ref:`geom <spatial-geom>` below. One can also define :ref:`pulleys <spatial-pulley>`
|
||||
which split the path in multiple branches. Each branch of the tendon path must start and end with a site, and if it
|
||||
has multiple obstacle geoms they must be separated by sites - so as to avoid the need for an iterative solver at the
|
||||
tendon level. This example illustrates a multi-branch tendon acting as a finger extensor, with a counter-weight
|
||||
instead of an actuator.
|
||||
This element creates a spatial tendon, which is a minimum-length path passing through specified via-points and
|
||||
wrapping around specified obstacle geoms. The objects along the path are defined with the sub-elements
|
||||
:ref:`site <spatial-site>` and :ref:`geom <spatial-geom>` below. One can also define :ref:`pulleys <spatial-pulley>`
|
||||
which split the path in multiple branches. Each branch of the tendon path must start and end with a site, and if it
|
||||
has multiple obstacle geoms they must be separated by sites - so as to avoid the need for an iterative solver at the
|
||||
tendon level. This example illustrates a multi-branch tendon acting as a finger extensor, with a counter-weight
|
||||
instead of an actuator.
|
||||
|
||||
| MuJoCo 2.0 introduced a second form of wrapping, where the tendon is constrained to pass through a geom rather than
|
||||
wrap around it. This is enabled automatically when a sidesite is specified and its position is inside the volume of
|
||||
the obstacle geom.
|
||||
MuJoCo 2.0 introduced a second form of wrapping, where the tendon is constrained to pass through a geom rather than
|
||||
wrap around it. This is enabled automatically when a sidesite is specified and its position is inside the volume of
|
||||
the obstacle geom.
|
||||
|
||||
| `tendon.xml <_static/tendon.xml>`__
|
||||
`tendon.xml <_static/tendon.xml>`__
|
||||
|
||||
:at:`name`: :at-val:`string, optional`
|
||||
Name of the tendon.
|
||||
@@ -4147,16 +4153,23 @@ specify them independently.
|
||||
Integer group to which the actuator belongs. This attribute can be used for custom tags. It is also used by the
|
||||
visualizer to enable and disable the rendering of entire groups of actuators.
|
||||
:at:`ctrllimited`: :at-val:`[false, true], "false"`
|
||||
If true, the control input to this actuator is automatically clamped to ctrlrange at runtime. If false, control input
|
||||
clamping is disabled. Note that control input clamping can also be globally disabled with the clampctrl attribute of
|
||||
option/ :ref:`flag <option-flag>`.
|
||||
If true, the control input to this actuator is automatically clamped to :at:`ctrlrange` at runtime. If false, control
|
||||
input clamping is disabled. Note that control input clamping can also be globally disabled with the :at:`clampctrl`
|
||||
attribute of :ref:`option/flag <option-flag>`.
|
||||
:at:`forcelimited`: :at-val:`[false, true], "false"`
|
||||
If true, the force output of this actuator is automatically clamped to forcerange at runtime. If false, force output
|
||||
If true, the force output of this actuator is automatically clamped to :at:`forcerange` at runtime. If false, force
|
||||
clamping is disabled.
|
||||
:at:`actlimited`: :at-val:`[false, true], "false"`
|
||||
If true, the internal state (activation) associated with this actuator is automatically clamped to :at:`actrange` at
|
||||
runtime. If false, activation clamping is disabled. See the :ref:`Activation clamping <CActRange>` section for more
|
||||
details.
|
||||
:at:`ctrlrange`: :at-val:`real(2), "0 0"`
|
||||
Range for clamping the control input. The compiler expects the first value to be smaller than the second value.
|
||||
:at:`forcerange`: :at-val:`real(2), "0 0"`
|
||||
Range for clamping the force output. The compiler expects the first value to be no greater than the second value.
|
||||
:at:`actrange`: :at-val:`real(2), "0 0"`
|
||||
Range for clamping the activation state. The compiler expects the first value to be no greater than the second value.
|
||||
See the :ref:`Activation clamping <CActRange>` section for more details.
|
||||
:at:`lengthrange`: :at-val:`real(2), "0 0"`
|
||||
Range of feasible lengths of the actuator's transmission. See :ref:`Length Range <CLengthRange>`.
|
||||
:at:`gear`: :at-val:`real(6), "1 0 0 0 0 0"`
|
||||
@@ -4262,12 +4275,13 @@ specify them independently.
|
||||
:el-prefix:`actuator/` **motor** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This and the next three elements are the :ref:`Actuator shortcuts <CActuator>` discussed earlier. When a
|
||||
such shortcut is encountered, the parser creates a :el:`general` actuator and sets its dynprm, gainprm and biasprm
|
||||
attributes to the internal defaults shown above, regardless of any default settings. It then adjusts dyntype, gaintype
|
||||
and biastype depending on the shortcut, parses any custom attributes (beyond the common ones), and translates them
|
||||
into regular attributes (i.e., attributes of the :el:`general` actuator type) as explained here.
|
||||
| This element creates a direct-drive actuator. The underlying :el:`general` attributes are set as follows:
|
||||
This and the next three elements are the :ref:`Actuator shortcuts <CActuator>` discussed earlier. When a
|
||||
such shortcut is encountered, the parser creates a :el:`general` actuator and sets its dynprm, gainprm and biasprm
|
||||
attributes to the internal defaults shown above, regardless of any default settings. It then adjusts dyntype, gaintype
|
||||
and biastype depending on the shortcut, parses any custom attributes (beyond the common ones), and translates them
|
||||
into regular attributes (i.e., attributes of the :el:`general` actuator type) as explained here.
|
||||
|
||||
This element creates a direct-drive actuator. The underlying :el:`general` attributes are set as follows:
|
||||
|
||||
========= ======= ========= =======
|
||||
Attribute Setting Attribute Setting
|
||||
@@ -4277,8 +4291,8 @@ gaintype fixed gainprm 1 0 0
|
||||
biastype none biasprm 0 0 0
|
||||
========= ======= ========= =======
|
||||
|
||||
|
|
||||
| This element does not have custom attributes. It only has common attributes, which are:
|
||||
|
||||
This element does not have custom attributes. It only has common attributes, which are:
|
||||
|
||||
|
||||
.. |actuator/motor attrib list| replace::
|
||||
@@ -4294,7 +4308,7 @@ biastype none biasprm 0 0 0
|
||||
:el-prefix:`actuator/` **position** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This element creates a position servo. The underlying :el:`general` attributes are set as follows:
|
||||
This element creates a position servo. The underlying :el:`general` attributes are set as follows:
|
||||
|
||||
========= ======= ========= =======
|
||||
Attribute Setting Attribute Setting
|
||||
@@ -4304,8 +4318,8 @@ gaintype fixed gainprm kp 0 0
|
||||
biastype affine biasprm 0 -kp 0
|
||||
========= ======= ========= =======
|
||||
|
||||
|
|
||||
| This element has one custom attribute in addition to the common attributes:
|
||||
|
||||
This element has one custom attribute in addition to the common attributes:
|
||||
|
||||
.. |actuator/position attrib list| replace::
|
||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
||||
@@ -4322,9 +4336,9 @@ biastype affine biasprm 0 -kp 0
|
||||
:el-prefix:`actuator/` **velocity** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This element creates a velocity servo. Note that in order create a PD controller, one has to define two actuators: a
|
||||
position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control
|
||||
inputs (reference position and reference velocity). The underlying :el:`general` attributes are set as follows:
|
||||
This element creates a velocity servo. Note that in order create a PD controller, one has to define two actuators: a
|
||||
position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control
|
||||
inputs (reference position and reference velocity). The underlying :el:`general` attributes are set as follows:
|
||||
|
||||
========= ======= ========= =======
|
||||
Attribute Setting Attribute Setting
|
||||
@@ -4334,8 +4348,8 @@ gaintype fixed gainprm kv 0 0
|
||||
biastype affine biasprm 0 0 -kv
|
||||
========= ======= ========= =======
|
||||
|
||||
|
|
||||
| This element has one custom attribute in addition to the common attributes:
|
||||
|
||||
This element has one custom attribute in addition to the common attributes:
|
||||
|
||||
.. |actuator/velocity attrib list| replace::
|
||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
||||
@@ -4352,8 +4366,8 @@ biastype affine biasprm 0 0 -kv
|
||||
:el-prefix:`actuator/` **cylinder** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This element is suitable for modeling pneumatic or hidraulic cylinders. The underlying :el:`general` attributes are
|
||||
set as follows:
|
||||
This element is suitable for modeling pneumatic or hidraulic cylinders. The underlying :el:`general` attributes are
|
||||
set as follows:
|
||||
|
||||
========= ======= ========= =============
|
||||
Attribute Setting Attribute Setting
|
||||
@@ -4363,8 +4377,8 @@ gaintype fixed gainprm area 0 0
|
||||
biastype affine biasprm bias(3)
|
||||
========= ======= ========= =============
|
||||
|
||||
|
|
||||
| This element has four custom attributes in addition to the common attributes:
|
||||
|
||||
This element has four custom attributes in addition to the common attributes:
|
||||
|
||||
.. |actuator/cylinder attrib list| replace::
|
||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
||||
@@ -4387,8 +4401,8 @@ biastype affine biasprm bias(3)
|
||||
:el-prefix:`actuator/` **muscle** (*)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| This element is used to model a muscle actuator, as described in the :ref:`Muscles actuators <CMuscle>`
|
||||
section. The underlying :el:`general` attributes are set as follows:
|
||||
This element is used to model a muscle actuator, as described in the :ref:`Muscles actuators <CMuscle>`
|
||||
section. The underlying :el:`general` attributes are set as follows:
|
||||
|
||||
========= ======= ========= ======================================================
|
||||
Attribute Setting Attribute Setting
|
||||
@@ -4398,8 +4412,8 @@ gaintype muscle gainprm range(2), force, scale, lmin, lmax, vmax, fpmax, fvm
|
||||
biastype muscle biasprm same as gainprm
|
||||
========= ======= ========= ======================================================
|
||||
|
||||
|
|
||||
| This element has nine custom attributes in addition to the common attributes:
|
||||
|
||||
This element has nine custom attributes in addition to the common attributes:
|
||||
|
||||
.. |actuator/muscle attrib list| replace::
|
||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
||||
@@ -4436,14 +4450,15 @@ biastype muscle biasprm same as gainprm
|
||||
**sensor** (*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
| This is a grouping element for sensor definitions. It does not have attributes. The outputs of all sensors are
|
||||
concatenated in the field mjData.sensordata which has size mjModel.nsensordata. This data is not used in any internal
|
||||
computations.
|
||||
| In addition to the sensors created with the elements below, the top-level function
|
||||
:ref:`mj_step` computes the quantities mjData.cacc, mjData.cfrc_int and mjData.crfc_ext
|
||||
corresponding to body accelerations and interaction forces. Some of these quantities are used to compute the output of
|
||||
certain sensors (force, acceleration etc.) but even if no such sensors are defined in the model, these quantities
|
||||
themselves are "features" that could be of interest to the user.
|
||||
This is a grouping element for sensor definitions. It does not have attributes. The outputs of all sensors are
|
||||
concatenated in the field mjData.sensordata which has size mjModel.nsensordata. This data is not used in any internal
|
||||
computations.
|
||||
|
||||
In addition to the sensors created with the elements below, the top-level function
|
||||
:ref:`mj_step` computes the quantities mjData.cacc, mjData.cfrc_int and mjData.crfc_ext
|
||||
corresponding to body accelerations and interaction forces. Some of these quantities are used to compute the output of
|
||||
certain sensors (force, acceleration etc.) but even if no such sensors are defined in the model, these quantities
|
||||
themselves are "features" that could be of interest to the user.
|
||||
|
||||
.. _sensor-touch:
|
||||
|
||||
@@ -4511,10 +4526,9 @@ simulate an inertial measurement unit (IMU).
|
||||
|
||||
This element creates a 3-axis force sensor. The sensor outputs three numbers, which are the interaction force between a
|
||||
child and a parent body, expressed in the site frame defining the sensor. The convention is that the site is attached to
|
||||
the child body, and the force points from the child towards the parent. To change the sign of the sensor reading, use
|
||||
the scale attribute. The computation here takes into account all forces acting on the system, including contacts as well
|
||||
as external perturbations. Using this sensor often requires creating a dummy body welded to its parent (i.e., having no
|
||||
joint elements).
|
||||
the child body, and the force points from the child towards the parent. The computation here takes into account all
|
||||
forces acting on the system, including contacts as well as external perturbations. Using this sensor often requires
|
||||
creating a dummy body welded to its parent (i.e., having no joint elements).
|
||||
|
||||
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
|
||||
See :ref:`CSensor`.
|
||||
|
||||
+58
-1
@@ -2,6 +2,63 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 2.2.0 (May 23, 2022)
|
||||
-----------------------------
|
||||
|
||||
Open Sourcing
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
1. MuJoCo is now fully open-source software. Newly available top level directories are:
|
||||
|
||||
a. ``src/``: All source files. Subrirectories correspond to the modules described in the Programming chapter
|
||||
:ref:`introduction<inIntro>`:
|
||||
|
||||
- ``src/engine/``: Core engine.
|
||||
- ``src/xml/``: XML parser.
|
||||
- ``src/user/``: Model compiler.
|
||||
- ``src/visualize/``: Abstract visualizer.
|
||||
- ``src/ui/``: UI framework.
|
||||
|
||||
b. ``test/``: Tests and corresponding asset files.
|
||||
|
||||
c. ``dist/``: Files related to packaging and binary distribution.
|
||||
|
||||
#. Added `contributor's guide <https://github.com/deepmind/mujoco/blob/main/CONTRIBUTING.md>`_ and
|
||||
`style guide <https://github.com/deepmind/mujoco/blob/main/STYLEGUIDE.md>`_.
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
3. Added :at:`actlimited` and :at:`actrange` attributes to :ref:`general actuators<general>`, for clamping actuator
|
||||
internal states (activations). This clamping is useful for integrated-velocity actuators, see the :ref:`Activation
|
||||
clamping <CActRange>` section for details.
|
||||
|
||||
#. ``mjData`` fields ``qfrc_unc`` (unconstrained forces) and ``qacc_unc`` (unconstrained accelerations) were renamed
|
||||
``qfrc_smooth`` and ``qacc_smooth``, respectively. While "unconstrained" is precise, "smooth" is more intelligible
|
||||
than "unc".
|
||||
|
||||
#. Public headers have been moved from ``/include`` to ``/include/mujoco/``, in line with the directory layout common in
|
||||
other open source projects. Developers are encouraged to include MuJoCo public headers in their own codebase via
|
||||
``#include <mujoco/filename.h>``.
|
||||
|
||||
#. The default shadow resolution specified by the :ref:`shadowsize<quality>` attribute was increased from 1024 to 4096.
|
||||
|
||||
#. Saved XMLs now use 2-space indents.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
8. Antialiasing was disabled for segmentation rendering. Before this change, if the :ref:`offsamples<quality>`
|
||||
attribute was greater than 0 (the default value is 4), pixels that overlapped with multiple geoms would receive
|
||||
averaged segmentation IDs, leading to incorrect or non-existant IDs. After this change :at:`offsamples` is ignored
|
||||
during segmentation rendering.
|
||||
|
||||
#. The value of the enable flag for the experimental multiCCD feature was made sequential with other enable flags.
|
||||
Sequentiality is assumed in the ``simulate`` UI and elsewhere.
|
||||
|
||||
#. Fix issue of duplicated meshes when saving models with OBJ meshes using mj_saveLastXML.
|
||||
|
||||
|
||||
Version 2.1.5 (Apr. 13, 2022)
|
||||
-----------------------------
|
||||
|
||||
@@ -106,7 +163,7 @@ API changes
|
||||
^^^^^^^^^^^
|
||||
|
||||
4. Moved definition of ``mjtNum`` floating point type into a new header
|
||||
`mjtnum.h <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`_.
|
||||
`mjtnum.h <https://github.com/deepmind/mujoco/blob/3577e2cf8bf841475b489aefff52276a39f24d51/include/mjtnum.h>`_.
|
||||
#. Renamed header `mujoco_export.h` to :ref:`mjexport.h<inHeader>`.
|
||||
#. Added ``mj_printFormattedData``, which accepts a format string for floating point numbers, for example to increase
|
||||
precision.
|
||||
|
||||
+1
-1
@@ -314,7 +314,7 @@ Putting all this together, the net force in generalized coordinates contributed
|
||||
.. math::
|
||||
\sum_i \nabla l_i(q) \; p_i \left(u_i, w_i, l_i(q), \dot{l}_i(q, v) \right)
|
||||
|
||||
This quantity is stored in ``mjData.qfrc_actuation``. It is added to the applied force vector :math:`\tau`, together
|
||||
This quantity is stored in ``mjData.qfrc_actuator``. It is added to the applied force vector :math:`\tau`, together
|
||||
with any user-defined forces in joint or Cartesian coordinates (which are stored in ``mjData.qfrc_applied`` and
|
||||
``mjData.xfrc_applied`` respectively).
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ sys.path.insert(0, os.path.abspath('../'))
|
||||
sys.path.append(os.path.abspath('ext'))
|
||||
|
||||
import sphinxcontrib.katex as katex # pylint: disable=g-import-not-at-top
|
||||
import sphinxcontrib.youtube as youtube # pylint: disable=g-import-not-at-top
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
@@ -42,6 +43,7 @@ master_doc = 'index'
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinxcontrib.katex',
|
||||
'sphinxcontrib.youtube',
|
||||
'sphinx_reredirects',
|
||||
]
|
||||
|
||||
|
||||
+290
-216
@@ -243,13 +243,13 @@ coordinates, but that effort is rarely justified.
|
||||
Frame orientations
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Several model elements have right-handed spatial frames associated with them. These are all the elements defined in
|
||||
the kinematic tree except for joints. A spatial frame is defined by its position and orientation. Specifying 3D
|
||||
positions is straightforward, but specifying 3D orientations can be challenging. This is why MJCF provides several
|
||||
alternative mechanisms. No matter which mechanism the user chooses, the frame orientation is always represented as a
|
||||
unit quaternion after compilation. Recall that a 3D rotation by angle *a* around axis given by the unit vector (*x, y,
|
||||
z*) corresponds to the quaternion (cos(*a*/2), sin(*a*/2) \* (*x, y, z*)). Also recall that every 3D orientation can
|
||||
be uniquely specified by a single 3D rotation by some angle around some axis.
|
||||
Several model elements have right-handed spatial frames associated with them. These are all the elements defined in the
|
||||
kinematic tree except for joints. A spatial frame is defined by its position and orientation. Specifying 3D positions is
|
||||
straightforward, but specifying 3D orientations can be challenging. This is why MJCF provides several alternative
|
||||
mechanisms. No matter which mechanism the user chooses, the frame orientation is always represented as a unit quaternion
|
||||
after compilation. Recall that a 3D rotation by angle :math:`a` around axis given by the unit vector :math:`(x, y, z)`
|
||||
corresponds to the quaternion :math:`(\cos(a/2), \: \sin(a/2) \cdot (x, y, z))`. Also recall that every 3D orientation
|
||||
can be uniquely specified by a single 3D rotation by some angle around some axis.
|
||||
|
||||
All MJCF elements that have spatial frames allow the five attributes listed below. The frame orientation is specified
|
||||
using at most one of these attributes. The :at:`quat` attribute has a default value corresponding to the null
|
||||
@@ -261,12 +261,12 @@ specified by the user, the frame is not rotated.
|
||||
conversions. Instead it is normalized to unit length and copied into mjModel during compilation. When a model is
|
||||
saved as MJCF, all frame orientations are expressed as quaternions using this attribute.
|
||||
:at:`axisangle`: :at-val:`real(4), optional`
|
||||
These are the quantities (*x, y, z, a*) mentioned above. The last number is the angle of rotation, in degrees or
|
||||
radians as specified by the :at:`angle` attribute of :ref:`compiler <compiler>`. The first three
|
||||
numbers determine a 3D vector which is the rotation axis. This vector is normalized to unit length during
|
||||
compilation, so the user can specify a vector of any non-zero length. Keep in mind that the rotation is right-handed;
|
||||
if the direction of the vector (*x, y, z*) is reversed this will result in the opposite rotation. Changing the sign
|
||||
of *a* can also be used to specify the opposite rotation.
|
||||
These are the quantities :math:`(x, y, z, a)` mentioned above. The last number is the angle of rotation, in degrees
|
||||
or radians as specified by the :at:`angle` attribute of :ref:`compiler <compiler>`. The first three numbers determine
|
||||
a 3D vector which is the rotation axis. This vector is normalized to unit length during compilation, so the user can
|
||||
specify a vector of any non-zero length. Keep in mind that the rotation is right-handed; if the direction of the
|
||||
vector :math:`(x, y, z)` is reversed this will result in the opposite rotation. Changing the sign of :math:`a` can
|
||||
also be used to specify the opposite rotation.
|
||||
:at:`euler`: :at-val:`real(3), optional`
|
||||
Rotation angles around three coordinate axes. The sequence of axes around which these rotations are applied is
|
||||
determined by the :at:`eulerseq` attribute of :ref:`compiler <compiler>` and is the same for the
|
||||
@@ -275,96 +275,110 @@ specified by the user, the frame is not rotated.
|
||||
The first 3 numbers are the X axis of the frame. The next 3 numbers are the Y axis of the frame, which is
|
||||
automatically made orthogonal to the X axis. The Z axis is then defined as the cross-product of the X and Y axes.
|
||||
:at:`zaxis`: :at-val:`real(3), optional`
|
||||
The Z axis of the frame. The compiler finds the minimal rotation that maps the vector (0,0,1) into the vector
|
||||
specified here. This determines the X and Y axes of the frame implicitly. This is useful for geoms with rotational
|
||||
symmetry around the Z axis, as well as lights - which are oriented along the Z axis of their frame.
|
||||
The Z axis of the frame. The compiler finds the minimal rotation that maps the vector :math:`(0, 0, 1)` into the
|
||||
vector specified here. This determines the X and Y axes of the frame implicitly. This is useful for geoms with
|
||||
rotational symmetry around the Z axis, as well as lights - which are oriented along the Z axis of their frame.
|
||||
|
||||
.. _CSolver:
|
||||
|
||||
Solver parameters
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The solver :ref:`Parameters <soParameters>` section of the Computation chapter explained the
|
||||
mathematical and algorithmic meaning of the quantities d, b, k which determine the behavior of the constraints in
|
||||
MuJoCo. Here we explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and
|
||||
:at:`solimp` which are available in all MJCF elements involving constraints. These parameters can be adjusted per
|
||||
constraint, or per defaults class, or left undefined - in which case MuJoCo uses the internal defaults shown below.
|
||||
Note also the override mechanism available in :ref:`option <option>`; it can be used to change all
|
||||
contact-related solver parameters at runtime, so as to experiment interactively with parameter settings or implement
|
||||
continuation methods for numerical optimization.
|
||||
The solver :ref:`Parameters <soParameters>` section of the Computation chapter explained the mathematical and
|
||||
algorithmic meaning of the quantities :math:`d, b, k` which determine the behavior of the constraints in MuJoCo. Here we
|
||||
explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and :at:`solimp` which are
|
||||
available in all MJCF elements involving constraints. These parameters can be adjusted per constraint, or per defaults
|
||||
class, or left undefined - in which case MuJoCo uses the internal defaults shown below. Note also the override mechanism
|
||||
available in :ref:`option <option>`; it can be used to change all contact-related solver parameters at runtime, so as to
|
||||
experiment interactively with parameter settings or implement continuation methods for numerical optimization.
|
||||
|
||||
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let a1
|
||||
denote the acceleration, v the velocity, r the position or residual (defined as 0 in friction dimensions), k and b the
|
||||
stiffness and damping of the virtual spring used to define the reference acceleration aref = -b*v - k*r. Let d be the
|
||||
constraint impedance, and a0 the acceleration in the absence of constraint force. Our earlier analysis revealed that
|
||||
the dynamics in constraint space are approximately
|
||||
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let
|
||||
:math:`a_1` denote the acceleration, :math:`v` the velocity, :math:`r` the position or residual (defined as 0 in
|
||||
friction dimensions), :math:`k` and :math:`b` the stiffness and damping of the virtual spring used to define the
|
||||
reference acceleration :math:`a_{\rm ref} = -b v - k r`. Let :math:`d` be the constraint impedance, and :math:`a_0` the
|
||||
acceleration in the absence of constraint force. Our earlier analysis revealed that the dynamics in constraint space are
|
||||
approximately
|
||||
|
||||
a1 + d \* (b v + k r) = (1 - d) \* a0
|
||||
.. math::
|
||||
a_1 + d \cdot (b v + k r) = (1 - d)\cdot a_0
|
||||
|
||||
Again, the parameters that are under the user's control are d, b, k. The remaining quantities are functions of the
|
||||
Again, the parameters that are under the user's control are :math:`d, b, k`. The remaining quantities are functions of the
|
||||
system state and are computed automatically at each time step.
|
||||
|
||||
First we explain the setting of the impedance d. Recall that d must lie between 0 and 1; internally MuJoCo clamps it
|
||||
to the range [:ref:`mjMINIMP mjMAXIMP <glNumeric>`] which is currently set to [0.0001 0.9999]. It
|
||||
causes the solver to interpolate between the unforced acceleration a0 and reference acceleration aref. Small values of
|
||||
d correspond to soft/weak constraints while large values of d correspond to strong/hard constraints. The user can set
|
||||
d to a constant, or take advantage of its interpolating property and make it position-dependent, i.e., a function of r.
|
||||
Position-dependent impedance can be used to model soft contact layers around objects, or define equality constraints
|
||||
that become stronger with larger violation (so as to approximate backlash for example). The shape of the function d(r)
|
||||
is determined by the element-specific parameter vector :at:`solimp`.
|
||||
First we explain the setting of the impedance :math:`d`. Recall that :math:`d` must lie between 0 and 1; internally
|
||||
MuJoCo clamps it to the range [:ref:`mjMINIMP mjMAXIMP <glNumeric>`] which is currently set to [0.0001 0.9999]. It
|
||||
causes the solver to interpolate between the unforced acceleration :math:`a_0` and reference acceleration
|
||||
:math:`a_{\rm ref}`. Small values of :math:`d` correspond to soft/weak constraints while large values of :math:`d`
|
||||
correspond to strong/hard constraints. The user can set :math:`d` to a constant, or take advantage of its interpolating
|
||||
property and make it position-dependent, i.e., a function of :math:`r`. Position-dependent impedance can be used to
|
||||
model soft contact layers around objects, or define equality constraints that become stronger with larger violation (so
|
||||
as to approximate backlash for example). The shape of the function :math:`d(r)` is determined by the element-specific
|
||||
parameter vector :at:`solimp`.
|
||||
|
||||
**solimp :** real(5), "0.9 0.95 0.001 0.5 2"
|
||||
The five numbers are (dmin, dmax, width, midpoint, power). They parameterize the function d(r). Prior to MuJoCo 2.0
|
||||
this attribute had three parameters, plus a global option specifying the shape of the function. In MuJoCo 2.0 we
|
||||
expanded the family of impedance functions while keeping it backward-compatible as follows. The user is allowed to
|
||||
set only the first three parameters, whose defaults are the same as in prior releases. The defaults for the last two
|
||||
parameters then generate the same function which was the default in prior releases (a sigmoid). The new
|
||||
|
||||
The five numbers are (dmin, dmax, width, midpoint, power). They parameterize the function :math:`d(r)`. Prior to
|
||||
MuJoCo 2.0 this attribute had three parameters, plus a global option specifying the shape of the function. In MuJoCo
|
||||
2.0 we expanded the family of impedance functions while keeping it backward-compatible as follows. The user is
|
||||
allowed to set only the first three parameters, whose defaults are the same as in prior releases. The defaults for
|
||||
the last two parameters then generate the same function which was the default in prior releases (a sigmoid). The new
|
||||
parameterization further allows the sigmoid to become shifted and skewed, as shown in the plots below for different
|
||||
values of the additional parameters. The plots actually show two reflected sigmoids, because the impedance function
|
||||
d(r) depends on the absolute value of r. This flexibility was added to allow better control of remote contact forces,
|
||||
and can also be used for other constraints. The power (of the polynomial spline used to generate the function) must
|
||||
be 1 or greater. The midpoint (specifying the inflection point) must be between 0 and 1, and is expressed in units of
|
||||
width. Note that when the power is 1, the function is linear regardless of the midpoint.
|
||||
:math:`d(r)` depends on the absolute value of :math:`r`. This flexibility was added to allow better control of remote
|
||||
contact forces, and can also be used for other constraints. The power (of the polynomial spline used to generate the
|
||||
function) must be 1 or greater. The midpoint (specifying the inflection point) must be between 0 and 1, and is
|
||||
expressed in units of width. Note that when the power is 1, the function is linear regardless of the midpoint.
|
||||
|image0|
|
||||
|
||||
These plots show the impedance d(r) on the vertical axis, as a function of the constraint violation r on the
|
||||
horizontal axis. The quantity r is computed as follows. For equality constraints, r equals the constraint violation
|
||||
which can be either positive or negative. For friction loss or friction dimensions of elliptic cones, r is always 0.
|
||||
For limits, normal directions of elliptic cones and all directions of pyramidal cones, r is the (limit or contact)
|
||||
distance minus the margin at which the constraint becomes active; for contacts this margin is actually margin-gap.
|
||||
Therefore limit and contact constraints are active when the corresponding r is negative.
|
||||
These plots show the impedance :math:`d(r)` on the vertical axis, as a function of the constraint violation :math:`r`
|
||||
on the horizontal axis. The quantity :math:`r` is computed as follows. For equality constraints, :math:`r` equals the
|
||||
constraint violation which can be either positive or negative. For friction loss or friction dimensions of elliptic
|
||||
cones, :math:`r` is always 0. For limits, normal directions of elliptic cones and all directions of pyramidal cones,
|
||||
:math:`r` is the (limit or contact) distance minus the margin at which the constraint becomes active; for contacts
|
||||
this margin is actually margin-gap. Therefore limit and contact constraints are active when the corresponding
|
||||
:math:`r` is negative.
|
||||
|
||||
Next we explain the setting of the stiffness k and damping b. The idea here is to re-parameterize the model in terms of
|
||||
the time constant and damping ratio of the above mass-spring-damper system. By "time constant" we mean the inverse of
|
||||
the natural frequency times the damping ratio. Constraints whose residual is identically 0 have first-order dynamics and
|
||||
the mass-spring-damper analysis does not apply. In that case the time constant is the rate of exponential decay of the
|
||||
constraint velocity, and the damping ratio is ignored. In addition to this format, MuJoCo 2.0 allows a second format
|
||||
where stiffness and damping are specified more directly.
|
||||
Next we explain the setting of the stiffness :math:`k` and damping :math:`b`. The idea here is to re-parameterize the
|
||||
model in terms of the time constant and damping ratio of the above mass-spring-damper system. By "time constant" we mean
|
||||
the inverse of the natural frequency times the damping ratio. Constraints whose residual is identically 0 have first-
|
||||
order dynamics and the mass-spring-damper analysis does not apply. In that case the time constant is the rate of
|
||||
exponential decay of the constraint velocity, and the damping ratio is ignored. In addition to this format, MuJoCo 2.0
|
||||
allows a second format where stiffness and damping are specified more directly.
|
||||
|
||||
**solref :** real(2), "0.02 1"
|
||||
There are two formats for this attribute, determined by the sign of the numbers. If both numbers are positive the
|
||||
specification is considered to be in the (timeconst, dampratio) format which has been available in MuJoCo all along.
|
||||
Otherwise the specification is considered to be in the new (-stiffness, -damping) format introduced in MuJoCo 2.0.
|
||||
We first describe the original format where the two numbers are (timeconst, dampratio). In this case we use a
|
||||
mass-spring-damper model to compute k, b after suitable scaling. Note that the effective stiffness d(r)*k and damping
|
||||
d(r)*b are scaled by the impedance d(r) which is a function of the distance r. Thus we cannot always achieve the
|
||||
specified mass-spring-damper properties, unless we completely undo the scaling by d. But the latter is undesirable
|
||||
because it would ruin the interpolating property, in particular the limit d = 0 would no longer disable the
|
||||
constraint. Instead we scale the stiffness and damping so that the damping ratio remains constant, while the time
|
||||
constant increases when d(r) gets smaller. The scaling formulas are
|
||||
b = 2 / (dmax \* timeconst)
|
||||
k = d(r) / (dmax \* dmax \* timeconst \* timeconst \* dampratio \* dampratio)
|
||||
specification is considered to be in the :math:`(\text{timeconst}, \text{dampratio})` format which has been available
|
||||
in MuJoCo all along. Otherwise the specification is considered to be in the new :math:`(-\text{stiffness}, -
|
||||
\text{damping})`, format introduced in MuJoCo 2.0. We first describe the original format where the two numbers are
|
||||
:math:`(\text{timeconst}, \text{dampratio})`. In this case we use a mass-spring-damper model to compute :math:`k, b`
|
||||
after suitable scaling. Note that the effective stiffness :math:`d(r) \cdot k` and damping :math:`d(r) \cdot b` are
|
||||
scaled by the impedance :math:`d(r)` which is a function of the distance :math:`r`. Thus we cannot always achieve the
|
||||
specified mass-spring-damper properties, unless we completely undo the scaling by :math:`d`. But the latter is
|
||||
undesirable because it would ruin the interpolating property, in particular the limit :math:`d=0` would no longer
|
||||
disable the constraint. Instead we scale the stiffness and damping so that the damping ratio remains constant, while
|
||||
the time constant increases when :math:`d(r)` gets smaller. The scaling formulas are
|
||||
|
||||
.. math::
|
||||
\begin{aligned}
|
||||
b &= 2 / (d_\text{max}\cdot \text{timeconst}) \\
|
||||
k &= d(r) / (d_\text{max}^2 \cdot \text{timeconst}^2 \cdot \text{dampratio}^2) \\
|
||||
\end{aligned}
|
||||
|
||||
The timeconst parameter should be at least two times larger than the simulation time step, otherwise the system can
|
||||
become too stiff relative to the numerical integrator (especially when Euler integration is used) and the simulation
|
||||
can go unstable. This is enforced internally, unless the :at:`refsafe` attribute of
|
||||
:ref:`flag <option-flag>` is set to false. The dampratio parameter would normally be set to 1,
|
||||
corresponding to critical damping. Smaller values result in under-damped or bouncy constraints, while larger values
|
||||
result in over-damped constraints.
|
||||
Next we describe the new format where the two numbers are (-stiffness, -damping). This allows more direct control
|
||||
over restitution in particular. We still apply some scaling so that the same numbers can be used with different
|
||||
impedances, but the scaling no longer depends on r and the two numbers no longer interact. The scaling formulas are
|
||||
b = damping / dmax
|
||||
k = stiffness / (dmax \* dmax)
|
||||
can go unstable. This is enforced internally, unless the :at:`refsafe` attribute of :ref:`flag <option-flag>` is set
|
||||
to false. The :math:`\text{dampratio}` parameter would normally be set to 1, corresponding to critical damping.
|
||||
Smaller values result in under-damped or bouncy constraints, while larger values result in over-damped constraints.
|
||||
Next we describe the new format where the two numbers are :math:`(-\text{stiffness}, -\text{damping})`. This allows
|
||||
more direct control over restitution in particular. We still apply some scaling so that the same numbers can be used
|
||||
with different impedances, but the scaling no longer depends on :math:`r` and the two numbers no longer interact. The
|
||||
scaling formulas are
|
||||
|
||||
.. math::
|
||||
\begin{aligned}
|
||||
b &= \text{damping} / d_\text{max} \\
|
||||
k &= \text{stiffness} / d_\text{max}^2 \\
|
||||
\end{aligned}
|
||||
|
||||
.. _CContact:
|
||||
|
||||
@@ -530,20 +544,18 @@ well as solver statistics per iteration. We can offer the following general guid
|
||||
Actuator shortcuts
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As explained in the :ref:`Actuation model <geActuation>` section of the Computation chapter, MuJoCo
|
||||
offers a flexible actuator model with transmission, activation dynamics and force generation components that can be
|
||||
specified independently. The full functionality can be accessed via the XML element
|
||||
:ref:`general <general>` which allows the user to create a variety of custom actuators. In addition,
|
||||
MJCF provides shortcuts for configuring common actuators. This is done via the XML elements
|
||||
:ref:`motor <motor>`, :ref:`position <position>`,
|
||||
:ref:`velocity <velocity>`, :ref:`cylinder <cylinder>`,
|
||||
:ref:`muscle <muscle>`. These are *not* separate model elements. Internally MuJoCo supports only one
|
||||
As explained in the :ref:`Actuation model <geActuation>` section of the Computation chapter, MuJoCo offers a flexible
|
||||
actuator model with transmission, activation dynamics and force generation components that can be specified
|
||||
independently. The full functionality can be accessed via the XML element :ref:`general <general>` which allows the user
|
||||
to create a variety of custom actuators. In addition, MJCF provides shortcuts for configuring common actuators. This is
|
||||
done via the XML elements :ref:`motor <motor>`, :ref:`position <position>`, :ref:`velocity <velocity>`, :ref:`cylinder
|
||||
<cylinder>`, :ref:`muscle <muscle>`. These are *not* separate model elements. Internally MuJoCo supports only one
|
||||
actuator type - which is why when an MJCF model is saved all actuators are written as :el:`general`. Shortcuts create
|
||||
general actuators implicitly, set their attributes to suitable values, and expose a subset of attributes with possibly
|
||||
different names. For example, :el:`position` creates a position servo with attribute :at:`kp` which is the servo
|
||||
gain. However :el:`general` does not have an attribute :at:`kp`. Instead the parser adjusts the gain and bias
|
||||
parameters of the general actuator in a coordinated way so as to mimic a position servo. The same effect could have
|
||||
been achieved by using :el:`general` directly, and setting its attributes to certain values as described below.
|
||||
different names. For example, :el:`position` creates a position servo with attribute :at:`kp` which is the servo gain.
|
||||
However :el:`general` does not have an attribute :at:`kp`. Instead the parser adjusts the gain and bias parameters of
|
||||
the general actuator in a coordinated way so as to mimic a position servo. The same effect could have been achieved by
|
||||
using :el:`general` directly, and setting its attributes to certain values as described below.
|
||||
|
||||
Actuator shortcuts also interact with defaults. Recall that the :ref:`default setting <CDefault>` mechanism involves
|
||||
classes, each of which has a complete collection of dummy elements (one of each element type) used to initialize the
|
||||
@@ -561,6 +573,53 @@ defaults class and in the creation of actual model elements. If a given model re
|
||||
create multiple defaults classes, or avoid using defaults for actuators and instead specify all their attributes
|
||||
explicitly.
|
||||
|
||||
.. _CActRange:
|
||||
|
||||
Activation clamping
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As described in the :ref:`Actuation model <geActuation>` section of the Computation chapter, MuJoCo supports actuators
|
||||
with internal dynamics whose states are called "activations". One useful application of these stateful actuators is the
|
||||
"integrated-velocity" actuator. Different from the :ref:`pure velocity<velocity>` actuators, which implement direct
|
||||
feedback on transmission target's velocity, *integrated-velocity* actuators couple an *integrator* with a *position-
|
||||
feedback* actuator. In this case the semantics of the activation state are "the target of the position actuator", and
|
||||
the semantics of the control signal are "the velocity of the target of the position actuator". Note that in real robotic
|
||||
systems this integrated-velocity actuator is the most common implementation of actuators with velocity semantics, rather
|
||||
than pure feedback on velocity which is often quite unstable (both in real life and in simulation).
|
||||
|
||||
In the case of integrated-velocity actuators, it is often desirable to *clamp* the activation state, since otherwise the
|
||||
position target would keep integrating beyond the joint limits, leading to loss of controllabillity. To see the effect
|
||||
of activation clamping, load the example model below:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<mujoco>
|
||||
<default>
|
||||
<joint axis="0 0 1" limited="true" range="-90 90" damping="0.3"/>
|
||||
<geom size=".1 .1 .1" type="box"/>
|
||||
<general gainprm="1" biastype="affine" biasprm="0 -1" dyntype="integrator"/>
|
||||
</default>
|
||||
|
||||
<worldbody>
|
||||
<body>
|
||||
<joint name="joint 1"/>
|
||||
<geom/>
|
||||
</body>
|
||||
<body pos=".3 0 0">
|
||||
<joint name="joint 2"/>
|
||||
<geom/>
|
||||
</body>
|
||||
</worldbody>
|
||||
|
||||
<actuator>
|
||||
<general name="unclamped" joint="joint 1"/>
|
||||
<general name="clamped" actlimited="true" actrange="-1.57 1.57"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
|
||||
Note that the :at:`actrange` attribute is always specified in native units (radians), even though the joint range
|
||||
can be either in degrees (the default) or radians, depending on the :ref:`compiler/angle <compiler>` attribute.
|
||||
|
||||
.. _CLengthRange:
|
||||
|
||||
Actuator length range
|
||||
@@ -637,103 +696,120 @@ the shortcut :ref:`muscle <muscle>` is more convenient. As with all other actuat
|
||||
production mechanism and the transmission are defined independently. Nevertheless, muscles only make (bio)physical
|
||||
sense when attached to tendon or joint transmissions. For concreteness we will assume a tendon transmission here.
|
||||
|
||||
First we discuss length and length scaling. The range of feasible lengths of the transmission (i.e., MuJoCo tendon)
|
||||
will play an important role; see :ref:`Length range <CLengthRange>` section above. In biomechanics, a muscle and a
|
||||
tendon are attached in series and form a muscle-tendon actuator. Our convention is somewhat different: in MuJoCo the
|
||||
entity that has spatial properties (in particular length and velocity) is the tendon, while the muscle is an abstract
|
||||
force-generating mechanism that pulls on the tendon. Thus the tendon length in MuJoCo corresponds to the muscle+tendon
|
||||
length in biomechanics. We assume that the biological tendon is inelastic, with constant length LT, while the
|
||||
biological muscle length LM varies over time. The MuJoCo tendon length is the sum of the biological muscle and tendon
|
||||
lengths:
|
||||
First we discuss length and length scaling. The range of feasible lengths of the transmission (i.e., MuJoCo tendon) will
|
||||
play an important role; see :ref:`Length range <CLengthRange>` section above. In biomechanics, a muscle and a tendon are
|
||||
attached in series and form a muscle-tendon actuator. Our convention is somewhat different: in MuJoCo the entity that
|
||||
has spatial properties (in particular length and velocity) is the tendon, while the muscle is an abstract force-
|
||||
generating mechanism that pulls on the tendon. Thus the tendon length in MuJoCo corresponds to the muscle+tendon length
|
||||
in biomechanics. We assume that the biological tendon is inelastic, with constant length :math:`L_T`, while the
|
||||
biological muscle length :math:`L_M` varies over time. The MuJoCo tendon length is the sum of the biological muscle and
|
||||
tendon lengths:
|
||||
|
||||
actuator_length = LT + LM
|
||||
.. math::
|
||||
\texttt{actuator\_length} = L_T + L_M
|
||||
|
||||
Another important constant is the optimal resting length of the muscle, denoted L0. It equals the length LM at which
|
||||
the muscle generates maximum active force at zero velocity. We do not ask the user to specify L0 and LT directly,
|
||||
because it is difficult to know their numeric values given the spatial complexity of the tendon routing and wrapping.
|
||||
Instead we compute L0 and LT automatically as follows. The length range computation described above already provided
|
||||
the operating range for LT + LM. In addition, we ask the user to specify the operating range for the muscle length LM
|
||||
scaled by the (still unknown) constant L0. This is done with the attribute range; the default scaled range is (0.75,
|
||||
1.05). Now we can compute the two constants, using the fact that the actual and scaled ranges have to map to each
|
||||
other:
|
||||
Another important constant is the optimal resting length of the muscle, denoted :math:`L_0`. It equals the length
|
||||
:math:`L_M` at which the muscle generates maximum active force at zero velocity. We do not ask the user to specify
|
||||
:math:`L_0` and :math:`L_T` directly, because it is difficult to know their numeric values given the spatial complexity
|
||||
of the tendon routing and wrapping. Instead we compute :math:`L_0` and :math:`L_T` automatically as follows. The length
|
||||
range computation described above already provided the operating range for :math:`L_T+L_M`. In addition, we ask the user
|
||||
to specify the operating range for the muscle length :math:`L_M` scaled by the (still unknown) constant :math:`L_0`.
|
||||
This is done with the attribute range; the default scaled range is :math:`(0.75, 1.05)`. Now we can compute the two
|
||||
constants, using the fact that the actual and scaled ranges have to map to each other:
|
||||
|
||||
(actuator_lengthrange[0] - LT) / L0 = range[0]
|
||||
|
||||
(actuator_lengthrange[1] - LT) / L0 = range[1]
|
||||
.. math::
|
||||
\begin{aligned}
|
||||
(\texttt{actuator\_lengthrange[0]} - L_T) / L_0 &= \texttt{range[0]} \\
|
||||
(\texttt{actuator\_lengthrange[1]} - L_T) / L_0 &= \texttt{range[1]} \\
|
||||
\end{aligned}
|
||||
|
||||
At runtime, we compute the scaled muscle length and velocity as:
|
||||
|
||||
L = (actuator_length - LT) / L0
|
||||
|
||||
V = actuator_velocity / L0
|
||||
.. math::
|
||||
\begin{aligned}
|
||||
L &= (\texttt{actuator\_length} - L_T) / L_0 \\
|
||||
V &= \texttt{actuator\_velocity} / L_0 \\
|
||||
\end{aligned}
|
||||
|
||||
The advantage of the scaled quantities is that all muscles behave similarly in that representation. The behavior is
|
||||
captured by the Force-Length-Velocity (FLV) function measured in many experimental papers. We approximate this
|
||||
function as follows:
|
||||
captured by the Force-Length-Velocity (:math:`\text{\small FLV}`) function measured in many experimental papers. We
|
||||
approximate this function as follows:
|
||||
|
||||
|image1|
|
||||
|
||||
The function is in the form:
|
||||
|
||||
FLV(L, V, act) = FL(L)*FV(V)*act + FP(L)
|
||||
.. math::
|
||||
\text{\small FLV}(L, V, \texttt{act}) = F_L(L)\cdot F_V(V)\cdot \texttt{act} + F_P(L)
|
||||
|
||||
Comparing to the general form of a MuJoCo actuator, we see that FL*FV is the actuator gain and FP is the actuator
|
||||
bias. FL is the active force as a function of length, while FV is the active force as a function of velocity. They are
|
||||
multiplied to obtain the overall active force (note the scaling by act which is the actuator activation). FP is the
|
||||
passive force which is always present regardless of activation. The output of the FLV function is the scaled muscle
|
||||
force. We multiply the scaled force by a muscle-specific constant F0 to obtain the actual force:
|
||||
Comparing to the general form of a MuJoCo actuator, we see that :math:`F_L\cdot F_V` is the actuator gain and
|
||||
:math:`F_P` is the actuator bias. :math:`F_L` is the active force as a function of length, while :math:`F_V` is the
|
||||
active force as a function of velocity. They are multiplied to obtain the overall active force (note the scaling by act
|
||||
which is the actuator activation). :math:`F_P` is the passive force which is always present regardless of activation.
|
||||
The output of the :math:`\text{\small FLV}` function is the scaled muscle force. We multiply the scaled force by a
|
||||
muscle-specific constant :math:`F_0` to obtain the actual force:
|
||||
|
||||
actuator_force = - FLV(L, V, act) \* F0
|
||||
.. math::
|
||||
\texttt{actuator\_force} = -\text{\small FLV}(L, V, \texttt{act}) \cdot F_0
|
||||
|
||||
The negative sign is because positive muscle activation generates pulling force. The constant F0 is the peak active
|
||||
force at zero velocity. It is related to the muscle thickness (i.e., physiological cross-sectional area or PCSA). If
|
||||
known, it can be set with the attribute force of element :ref:`muscle <muscle>`. If it is not known, we
|
||||
set it to -1 which is the default. In that case we rely on the fact that larger muscles tend to act on joints that
|
||||
move more weight. The attribute scale defines this relationship as:
|
||||
The negative sign is because positive muscle activation generates pulling force. The constant :math:`F_0` is the peak
|
||||
active force at zero velocity. It is related to the muscle thickness (i.e., physiological cross-sectional area or PCSA).
|
||||
If known, it can be set with the attribute force of element :ref:`muscle <muscle>`. If it is not known, we set it to
|
||||
:math:`-1` which is the default. In that case we rely on the fact that larger muscles tend to act on joints that move
|
||||
more weight. The attribute scale defines this relationship as:
|
||||
|
||||
F0 = scale / actuator_acc0
|
||||
.. math::
|
||||
F_0 = \text{scale} / \texttt{actuator\_acc0}
|
||||
|
||||
The quantity actuator_acc0 is precomputed by the model compiler. It is the norm of the joint acceleration caused by
|
||||
unit force acting on the actuator transmission. Intuitively, scale determines how strong the muscle is "on average"
|
||||
while its actual strength depends on the geometric and inertial properties of the entire model.
|
||||
The quantity :math:`\texttt{actuator\_acc0}` is precomputed by the model compiler. It is the norm of the joint
|
||||
acceleration caused by unit force acting on the actuator transmission. Intuitively, :math:`\text{scale}` determines how
|
||||
strong the muscle is "on average" while its actual strength depends on the geometric and inertial properties of the
|
||||
entire model.
|
||||
|
||||
Thus far we encountered three constants that define the properties of an individual muscle: LT, L0, F0. In addition,
|
||||
the function FLV itself has several parameters illustrated in the above figure: lmin, lmax, vmax, fpmax, fvmax. These
|
||||
are supposed to be the same for all muscles, however different experimental papers suggest different shapes of the FLV
|
||||
function, thus users familiar with that literature may want to adjust them. We provide the MATLAB function
|
||||
`FLV.m <_static/FLV.m>`__ which was used to generate the above figure and shows how we compute the FLV function.
|
||||
Thus far we encountered three constants that define the properties of an individual muscle: :math:`L_T, L_0, F_0`. In
|
||||
addition, the function :math:`\text{\small FLV}` itself has several parameters illustrated in the above figure:
|
||||
:math:`l_\text{min}, l_\text{max}, v_\text{max}, f_\text{pmax}, f_\text{vmax}`. These are supposed to be the same for
|
||||
all muscles, however different experimental papers suggest different shapes of the FLV function, thus users familiar
|
||||
with that literature may want to adjust them. We provide the MATLAB function `FLV.m <_static/FLV.m>`__ which was used to
|
||||
generate the above figure and shows how we compute the :math:`\text{\small FLV}` function.
|
||||
|
||||
Before embarking on a mission to design more accurate FLV functions, consider the fact that the operating range of the
|
||||
muscle has a bigger effect than the shape of the FLV function, and in many cases this parameter is unknown. Below is a
|
||||
graphical illustration:
|
||||
Before embarking on a mission to design more accurate :math:`\text{\small FLV}` functions, consider the fact that the
|
||||
operating range of the muscle has a bigger effect than the shape of the :math:`\text{\small FLV}` function, and in many
|
||||
cases this parameter is unknown. Below is a graphical illustration:
|
||||
|
||||
|image2|
|
||||
|
||||
This figure format is common in the biomechanics literature, showing the operating range of each muscle superimposed
|
||||
on the normalized FL curve (ignore the vertical displacement). Our default range is shown in black. The blue curves
|
||||
are experimental data for two arm muscles. One can find muscles with small range, large range, range spanning the
|
||||
ascending portion of the FL curve, or the descending portion, or some of both. Now suppose you have a model with 50
|
||||
muscles. Do you believe that someone did careful experiments and measured the operating range for every muscle in your
|
||||
model, taking into account all the joints that the muscle spans? If not, then it is better to think of
|
||||
This figure format is common in the biomechanics literature, showing the operating range of each muscle superimposed on
|
||||
the normalized :math:`\text{FL}` curve (ignore the vertical displacement). Our default range is shown in black. The blue
|
||||
curves are experimental data for two arm muscles. One can find muscles with small range, large range, range spanning the
|
||||
ascending portion of the :math:`\text{FL}` curve, or the descending portion, or some of both. Now suppose you have a
|
||||
model with 50 muscles. Do you believe that someone did careful experiments and measured the operating range for every
|
||||
muscle in your model, taking into account all the joints that the muscle spans? If not, then it is better to think of
|
||||
musculo-skeletal models as having the same general behavior as the biological system, while being different in various
|
||||
details - including details that are of great interest to some research community. For most muscle properties which
|
||||
modelers consider constant and known, there is an experimental paper showing that they vary under some conditions.
|
||||
This is not to discourage people from building accurate models, but rather to discourage people from believing too
|
||||
strongly in their models. Modeling in biology is quite different from modeling in physics and engineering... which is
|
||||
why we find it ironic when people in Robotics complain that building accurate robot models is hard.
|
||||
modelers consider constant and known, there is an experimental paper showing that they vary under some conditions. This
|
||||
is not to discourage people from building accurate models, but rather to discourage people from believing too strongly
|
||||
in their models. Modeling in biology is quite different from modeling in physics and engineering... which is why we find
|
||||
it ironic when people in Robotics complain that building accurate robot models is hard.
|
||||
|
||||
Coming back to our muscle model, there is the muscle activation act. This is the state of a first-order nonlinear
|
||||
filter whose input is the control signal. The filter dynamics are:
|
||||
|
||||
d act / dt = (ctrl - act) / tau(ctrl, act)
|
||||
|
||||
.. math::
|
||||
\frac{\partial}{\partial t}\texttt{act} = \frac{\texttt{ctrl} - \texttt{act}}{\tau(\texttt{ctrl}, \texttt{act})}
|
||||
|
||||
Internally the control signal is clamped to [0, 1] even if the actuator does not have a control range specified. There
|
||||
are two time constants specified with the attribute timeconst, namely timeconst = (tau_act, tau_deact) with defaults
|
||||
(0.01, 0.04). The effective time constant tau is then computed at runtime as:
|
||||
are two time constants specified with the attribute timeconst, namely :math:`\text{timeconst} = (\tau_\text{act},
|
||||
\tau_\text{deact})` with defaults :math:`(0.01, 0.04)`. Following `Millard et al. (2013)
|
||||
<https://doi.org/10.1115/1.4023390>`__, the effective time constant :math:`\tau` is then computed at runtime as:
|
||||
|
||||
tau(ctrl, act) = tau_act \* (0.5 + 1.5*act), if ctrl > act
|
||||
|
||||
tau(ctrl, act) = tau_deact / (0.5 + 1.5*act), if ctrl <= act
|
||||
.. math::
|
||||
\tau(\texttt{ctrl}, \texttt{act}) =
|
||||
\begin{cases}
|
||||
\tau_\text{act} \cdot (0.5 + 1.5\cdot\texttt{act}) & \texttt{ctrl} \gt \texttt{act} \\
|
||||
\tau_\text{deact} / (0.5 + 1.5\cdot\texttt{act}) & \texttt{ctrl} \leq \texttt{act}
|
||||
\end{cases}
|
||||
|
||||
Now we summarize the attributes of element :ref:`muscle <muscle>` which users may want to adjust,
|
||||
depending on their familiarity with the biomechanics literature and availability of detailed measurements with regard
|
||||
@@ -747,8 +823,8 @@ scale
|
||||
This can be adjusted separately for each muscle, but it makes more sense to set it once in the
|
||||
:ref:`default <default>` element.
|
||||
force
|
||||
If you know the peak active force F0 of the individual muscles, enter it here. Many experimental papers contain this
|
||||
data.
|
||||
If you know the peak active force :math:`F_0` of the individual muscles, enter it here. Many experimental papers
|
||||
contain this data.
|
||||
range
|
||||
The operating range of the muscle in scaled lengths is also available in some papers. It is not clear how reliable
|
||||
such measurements are (given that muscles act on many joints) but they do exist. Note that the range differs
|
||||
@@ -756,11 +832,11 @@ range
|
||||
timeconst
|
||||
Muscles are composed of slow-twitch and fast-twitch fibers. The typical muscle is mixed, but some muscles have a
|
||||
higher proportion of one or the other fiber type, making them faster or slower. This can be modeled by adjusting the
|
||||
time constants. The vmax parameter of the FLV function should also be adjusted accordingly.
|
||||
time constants. The vmax parameter of the :math:`\text{\small FLV}` function should also be adjusted accordingly.
|
||||
lmin, lmax, vmax, fpmax, fvmax
|
||||
These are the parameters controlling the shape of the FLV function. Advanced users can experiment with them; see
|
||||
MATLAB function `FLV.m <_static/FLV.m>`__. Similar to the scale setting, if you want to change the FLV
|
||||
parameters for all muscles, do so in the :ref:`default <default>` element.
|
||||
These are the parameters controlling the shape of the :math:`\text{\small FLV}` function. Advanced users can
|
||||
experiment with them; see MATLAB function `FLV.m <_static/FLV.m>`__. Similar to the scale setting, if you want to
|
||||
change the :math:`\text{\small FLV}` parameters for all muscles, do so in the :ref:`default <default>` element.
|
||||
Custom model
|
||||
Instead of adjusting the parameters of our muscle model, users can implement a different model, by setting gaintype,
|
||||
biastype and dyntype of a :ref:`general <general>` actuator to "user" and providing callbacks at
|
||||
@@ -777,17 +853,15 @@ simulations. To help MuJoCo users convert OpenSim models, here we summarize the
|
||||
|
||||
The activation dynamics model is identical to OpenSim, including the default time constants.
|
||||
|
||||
The FLV function is not exactly the same, but both MuJoCo and OpenSim approximate the same experimental data, so they
|
||||
are very close. For a description of the OpenSim model and summary of relevant experimental data, see:
|
||||
|
||||
Millard et al, "Flexing computational muscle: modeling and simulation of musculotendon dynamics", J Biomech Eng. 2013
|
||||
Feb;135(2)
|
||||
The :math:`\text{\small FLV}` function is not exactly the same, but both MuJoCo and OpenSim approximate the same
|
||||
experimental data, so they are very close. For a description of the OpenSim model and summary of relevant experimental
|
||||
data, see `Millard et al. (2013) <https://doi.org/10.1115/1.4023390>`__.
|
||||
|
||||
We assume inelastic tendons while OpenSim can model tendon elasticity. We decided not to do that here, because tendon
|
||||
elasticity requires fast-equilibrium assumptions which in turn require various tweaks and are prone to simulation
|
||||
instability. In practice tendons are quite stiff, and their effect can be captured approximately by stretching the FL
|
||||
curve corresponding to the inelastic case (Zajac 89). This can be done in MuJoCo by shortening the muscle operating
|
||||
range.
|
||||
instability. In practice tendons are quite stiff, and their effect can be captured approximately by stretching the
|
||||
:math:`\text{FL}` curve corresponding to the inelastic case (`Zajac (1989)
|
||||
<https://pubmed.ncbi.nlm.nih.gov/2676342/>`__). This can be done in MuJoCo by shortening the muscle operating range.
|
||||
|
||||
Pennation angle (i.e., the angle between the muscle and the line of force) is not modeled in MuJoCo and is assumed to
|
||||
be 0. This effect can be approximated by scaling down the muscle force and also adjusting the operating range.
|
||||
@@ -885,9 +959,9 @@ see the XML model files in the distribution for the complete examples.
|
||||
.. code-block:: xml
|
||||
|
||||
<worldbody>
|
||||
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
|
||||
The above XML is all it takes to create a system with 1000 particles with initial positions on a 10-10-10 grid, and
|
||||
@@ -908,11 +982,11 @@ simulation at much larger timesteps (this model is stable at 30 ms timestep and
|
||||
.. code-block:: xml
|
||||
|
||||
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<tendon kind="main" width="0.01"/>
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
<pin coord="1"/>
|
||||
<pin coord="13"/>
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<tendon kind="main" width="0.01"/>
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
<pin coord="1"/>
|
||||
<pin coord="13"/>
|
||||
</composite>
|
||||
|
||||
The grid type can create 1D or 2D grids, depending on the :at:`count` attribute. Here we illustrate 1D grids. These
|
||||
@@ -930,10 +1004,10 @@ example; in that case the parent body would be moving, and the first element bod
|
||||
.. code-block:: xml
|
||||
|
||||
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
||||
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
|
||||
<geom size=".02"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
|
||||
<geom size=".02"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
</composite>
|
||||
|
||||
A 2D grid can be used to simulate cloth. What it really simulates is a 2D grid of spheres connected with
|
||||
@@ -950,11 +1024,11 @@ absence of textures. When textures are present (left) the benefits of subdivisio
|
||||
.. code-block:: xml
|
||||
|
||||
<body name="B10" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
<freejoint/>
|
||||
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
|
||||
The remaining composite object types create kinematic trees of element bodies, and the parent body becomes the root of
|
||||
@@ -978,12 +1052,12 @@ The loop is similar to a rope but the first and last element bodies are connecte
|
||||
.. code-block:: xml
|
||||
|
||||
<body name="B3_5" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
|
||||
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
<freejoint/>
|
||||
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
|
||||
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
|
||||
The cloth type is an alternative to a 2D grid, and has somewhat different properties. Similar to rope vs. 1D grid, the
|
||||
@@ -1004,11 +1078,11 @@ some damping for stable integration. The parameters can be found in the XML mode
|
||||
.. code-block:: xml
|
||||
|
||||
<body pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="box" count="7 7 7" spacing="0.04">
|
||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
<freejoint/>
|
||||
<composite type="box" count="7 7 7" spacing="0.04">
|
||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
|
||||
The box type, as well as the cylinder and ellipsoid types below, are used to model soft 3D objects. The element bodies
|
||||
@@ -1036,11 +1110,11 @@ points to the outside, thus creating a thicker shell which is harder to penetrat
|
||||
.. code-block:: xml
|
||||
|
||||
<body pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
|
||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
<freejoint/>
|
||||
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
|
||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
|
||||
Cylinders and ellipsoids are created in the same way as boxes. The only difference is that the reference positions of
|
||||
@@ -1141,11 +1215,11 @@ Here is an example extension section of a URDF model:
|
||||
.. code-block:: xml
|
||||
|
||||
<robot name="darwin">
|
||||
<mujoco>
|
||||
<compiler meshdir="../mesh/darwin/" balanceinertia="true"/>
|
||||
</mujoco>
|
||||
<link name="MP_BODY">
|
||||
...
|
||||
<mujoco>
|
||||
<compiler meshdir="../mesh/darwin/" balanceinertia="true"/>
|
||||
</mujoco>
|
||||
<link name="MP_BODY">
|
||||
...
|
||||
</robot>
|
||||
|
||||
The above extensions make URDF more usable but still limited. If the user wants to build models taking full advantage of
|
||||
@@ -1179,8 +1253,8 @@ orientation:
|
||||
.. code-block:: xml
|
||||
|
||||
<body>
|
||||
<joint name="J1" type="hinge" pos="0 0 0" axis="0 0 1" armature="0.01"/>
|
||||
<joint name="J2" type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="-1 1"/>
|
||||
<joint name="J1" type="hinge" pos="0 0 0" axis="0 0 1" armature="0.01"/>
|
||||
<joint name="J2" type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="-1 1"/>
|
||||
</body>
|
||||
|
||||
Thus the overall rotation of the body relative to its parent is J1+J2. Now define an actuator acting only on J1. The
|
||||
@@ -1249,12 +1323,12 @@ in a visible way, and the energy fluctuates around the initial value instead of
|
||||
.. code-block:: xml
|
||||
|
||||
<worldbody>
|
||||
<geom type="plane" size="1 1 .1"/>
|
||||
<geom type="plane" size="1 1 .1"/>
|
||||
|
||||
<body pos="0 0 1">
|
||||
<freejoint/>
|
||||
<geom type="sphere" size="0.1" solref="-1000 0"/>
|
||||
</body>
|
||||
<body pos="0 0 1">
|
||||
<freejoint/>
|
||||
<geom type="sphere" size="0.1" solref="-1000 0"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
|
||||
.. _CSize:
|
||||
|
||||
+29
-3
@@ -640,6 +640,32 @@ interpreted as MKS, then forces and torques are in Newton and Newton-Meter, resp
|
||||
are using MKS, angular velocities reported by :ref:`gyroscopes<sensor-gyro>` would be in rad/s while stiffness of hinge
|
||||
joints would be in Nm/rad.
|
||||
|
||||
|
||||
.. _SurprisingCollisions:
|
||||
|
||||
Surprising Collisions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
MuJoCo by default excludes collisions between geoms that belong to body pairs which have a direct parent-child
|
||||
relationship. For example, consider the arm model in the :ref:`Examples` section above: there is no collision at the
|
||||
"elbow" even though the capsule geoms are penetrating, because the forearm is an immediate child of the upper arm.
|
||||
|
||||
However, this exclusion is **not applied if the parent is a static body** i.e., the world body, or a body without any
|
||||
degrees of freedom relative to the world body. This behavior, documented in the :ref:`Collision detection<Collision>`
|
||||
section, prevents objects from falling through the floor or moving through walls. However, this behavior often leads to
|
||||
the following situation:
|
||||
|
||||
The user comments out the root joint of a floating-base model, perhaps in order to prevent it from falling; now that the
|
||||
base body is counted as static, new collisions appear that were not there before and the user is confused. There are two
|
||||
easy ways to avoid this problem:
|
||||
|
||||
1. Don't remove the root joint. Perhaps it is enough to :ref:`disable gravity<option-flag>` and possibly add some
|
||||
:ref:`fluid viscosity<option>` in order to prevent your model from moving around too much.
|
||||
|
||||
2. Use :ref:`collision filtering<Collision>` to explicitly disable the unwanted collisions, either by setting the
|
||||
relevant :at:`contype` and :at:`conaffinity` attributes, or by using a contact :ref:`exclude <exclude>` directive.
|
||||
|
||||
|
||||
.. _NotObject:
|
||||
|
||||
Not object-oriented
|
||||
@@ -707,7 +733,7 @@ first, followed by the limits of the second joint etc. This ordering reflects th
|
||||
row-major format.
|
||||
|
||||
The available element types are defined in
|
||||
`mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h#L243>`_, in the enum type :ref:`mjtObj`.
|
||||
`mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h#L243>`_, in the enum type :ref:`mjtObj`.
|
||||
These enums are mostly used internally. One exception are the functions :ref:`mj_name2id` and :ref:`mj_id2name` in the
|
||||
MuJoCo API, which map element names to integer ids and vice versa. These functions take an element type as input.
|
||||
|
||||
@@ -761,8 +787,8 @@ properties.
|
||||
Sites are light geoms. They have the same appearance properties but cannot participate in collisions and cannot be used
|
||||
to infer body masses. On the other hand sites can do things that geoms cannot do: they can specify the volumes of touch
|
||||
sensors, the attachment of IMU sensors, the routing of spatial tendons, the end-points of slider-crank actuators. These
|
||||
are all spatial quantities, and yet they do not correspond to entities that should have mass or collide other entities -
|
||||
which is why the site element was created. Sites can also be used to specify points (or rather frames) of interest to
|
||||
are all spatial quantities, and yet they do not correspond to entities that should have mass or collide other entities
|
||||
-- which is why the site element was created. Sites can also be used to specify points (or rather frames) of interest to
|
||||
the user.
|
||||
|
||||
The following example illustrates the point that multiple sites and geoms can be attached to the same body: two sites
|
||||
|
||||
+183
-160
@@ -2,6 +2,8 @@
|
||||
Programming
|
||||
===========
|
||||
|
||||
.. _inIntro:
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
@@ -10,32 +12,16 @@ is a dynamic library compatible with Windows, Linux and macOS, which requires a
|
||||
library exposes the full functionality of the simulator through a compiler-independent shared-memory C API. It can also
|
||||
be used in C++ programs.
|
||||
|
||||
MuJoCo is a free product currently distributed as a pre-built dynamic library and will soon be made available as an
|
||||
open-source project. The software distribution contains a compiled version of GLFW which is used in the code samples to
|
||||
create an OpenGL window and direct user input to it. The distribution for each platform contains the following dynamic
|
||||
library:
|
||||
|
||||
.. code-block:: Text
|
||||
|
||||
Windows: mujoco.dll (stub library: mujoco.lib)
|
||||
|
||||
Linux: mujoco.so.2.1.5
|
||||
|
||||
macOS: mujoco.2.1.5.dylib
|
||||
|
||||
Even though MuJoCo is a single dynamic library with unified C API, it contains several modules, some of which are
|
||||
implemented in C++. We have taken advantage of the convenience of C++ for functionality that is used before the
|
||||
simulation starts (namely the parser and compiler), and have gone to the trouble of writing carefully-tuned C code for
|
||||
all runtime functionality. The modules are:
|
||||
The MuJoCo codebase is organized into subdirectories corresponding to different major areas of functionality:
|
||||
|
||||
Engine
|
||||
The simulator (or physics engine) is written in C. It is responsible for all runtime computations.
|
||||
Parser
|
||||
The XML parser is written in C++. It can parse MJCF models and URDF models, converting them into an internal mjCModel
|
||||
C++ object which is not directly exposed to the user.
|
||||
Compiler
|
||||
The compiler is written in C++. It takes an mjCModel C++ object constructed by the parser, and converts it into an
|
||||
mjModel C structure used at runtime.
|
||||
Simulator
|
||||
The simulator (or physics engine) is written in C. It is responsible for all runtime computations.
|
||||
Abstract visualizer
|
||||
The abstract visualizer is written in C. It generates a list of abstract geometric entities representing the
|
||||
simulation state, with all information needed for actual rendering. It also provides abstract mouse hooks for camera
|
||||
@@ -54,43 +40,83 @@ UI framework
|
||||
Getting started
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The software distribution is a single .zip (Windows) or .tar.gz (Mac and Linux) archive whose name contains the platform
|
||||
and software version, e.g. mujoco210_windows.zip. There is no installer. Simply unzip this archive in a directory of
|
||||
your choice (where you have write access). You may need to use chmod to set execute permissions or otherwise give
|
||||
permissions to run the libraries. From the bin subdirectory, you can now run the precompiled code samples, for example:
|
||||
MuJoCo is an open source project. Pre-built dynamic libraries are available for x86_64 and arm64 machines running
|
||||
Windows, Linux, and macOS. These can be downloaded from the `GitHub Releases page <https://github.com/deepmind/mujoco/releases>`_.
|
||||
Users who do not intend to develop or modify core MuJoCo code are encouraged to use our pre-built libraries, as these
|
||||
come bundled with the same versions of dependencies those that we regularly test against, and benefit from build flags
|
||||
that have been tuned for performance. Our pre-built libraries are almost entirely self-contained and do not require
|
||||
other any library to be present, other than the standard C runtime. We also hide all symbols corresponding apart from
|
||||
those that form MuJoCo's public API, thus ensuring that it can coexist with any other libraries that may be loaded into
|
||||
the process (including other versions of libraries that MuJoCo depends on).
|
||||
|
||||
The pre-built distribution is a single .zip on Windows, .dmg on macOS, and .tar.gz on Linux. There is no installer.
|
||||
On Windows and Linux, simply extract the archive in a directory of your choice. From the ``bin`` subdirectory, you can
|
||||
now run the precompiled code samples, for example:
|
||||
|
||||
.. code-block:: Text
|
||||
|
||||
Windows: simulate ..\model\humanoid.xml
|
||||
Linux and macOS: ./simulate ../model/humanoid.xml
|
||||
|
||||
Prior to MuJoCo 2.0, running the code samples needed LD_LIBRARY_PATH on Linux. As of MuJoCo 2.0, they are compiled with
|
||||
"rpath $ORIGIN" so the library is found in the executable directory (if it is not in the path).
|
||||
|
||||
The directory structure is shown below. Users can re-organize it if needed, as well as install the dynamic libraries in
|
||||
other directories and set the path accordingly. The only file created automatically is MUJOCO_LOG.TXT in the executable
|
||||
directory; it contains error and warning messages, and can be deleted at any time.
|
||||
|
||||
.. code-block:: Text
|
||||
|
||||
mujoco210
|
||||
bin - dynamic libraries, executables, MUJOCO_LOG.TXT
|
||||
doc - README.txt and REFERENCE.txt
|
||||
include - header files needed to develop with MuJoCo
|
||||
model - model collection (extra models available on the Forum)
|
||||
sample - code samples and makefile need to build them
|
||||
bin - dynamic libraries, executables, MUJOCO_LOG.TXT
|
||||
doc - README.txt and REFERENCE.txt
|
||||
include - header files needed to develop with MuJoCo
|
||||
model - model collection
|
||||
sample - code samples and makefile need to build them
|
||||
|
||||
After verifying that the simulator works, the next step is to re-compile the code samples so as to ensure that the
|
||||
development environment is properly installed. The distribution includes a platform-specific makefile in the sample
|
||||
subdirectory, which assumes Visual Studio on Windows, GCC on Linux and Clang on macOS. On Windows, remember to open a
|
||||
Visual Studio command prompt with native x64 tools. Assuming the compilation succeeded and the resulting executables in
|
||||
the bin subdirectory work, you are ready to start developing with MuJoCo.
|
||||
After verifying that the simulator works, you may also want to re-compile the code samples to ensure that you have a
|
||||
working development environment. We provide Makefiles for `Windows <https://github.com/deepmind/mujoco/blob/main/sample/Makefile.windows>`_,
|
||||
`macOS <https://github.com/deepmind/mujoco/blob/main/sample/Makefile.macos>`_, and
|
||||
`Linux <https://github.com/deepmind/mujoco/blob/main/sample/Makefile>`_, and also a cross-platform
|
||||
`CMake <https://github.com/deepmind/mujoco/blob/main/sample/CMakeLists.txt>`_ setup that can be used to build sample
|
||||
applications independently of the MuJoCo library itself. If you are using the vanilla Makefile, we assume that you are
|
||||
using Visual Studio on Windows and LLVM/Clang on Linux. On Windows, you also need to either open a Visual Studio command
|
||||
prompt with native x64 tools or call the ``vcvarsall.bat`` script that comes with your MSVC installation to set up the
|
||||
appropriate environment variables.
|
||||
|
||||
As already mentioned, MuJoCo is a compiler-independent library. In theory the user should be able to switch to any
|
||||
compiler of their choice. In practice we are using C++11 features as well as std:: functionality internally, and despite
|
||||
our efforts to statically link all necessary runtime libraries, this is not always possible - especially on Linux where
|
||||
licensing restrictions prevent static linking. If MuJoCo fails to start because of missing or incompatible dynamic
|
||||
libraries, please install the necessary libraries.
|
||||
On macOS, the DMG disk image contains ``MuJoCo.app``, which you can double-click to launch the ``simulate`` GUI.
|
||||
You can also drag ``MuJoCo.app`` into the ``/Application`` on your system, as you would to install any other app.
|
||||
While ``MuJoCo.app`` may look like a file, it is in fact an `Application Bundle <https://developer.apple.com/go/?id=bundle-structure>`_,
|
||||
which is a directory that contains executable binaries for all of MuJoCo's sample applications, along with an embedded
|
||||
`framework <https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WhatAreFrameworks.html>`_,
|
||||
which is a subdirectory containing the MuJoCo dynamic library and all of its public headers. In other words,
|
||||
``MuJoCo.app`` contains all the same files that are shipped in the archive on Windows and Linux. To see this, right
|
||||
click (or control-click) on ``MuJoCo.app`` and click "Show Package Contents".
|
||||
|
||||
As mentioned above, ``mujoco.framework`` contains the library and headers that are necessary to build any application
|
||||
that depends on MuJoCo. If you are using Xcode, you can import it as a framework dependency on your project. (This also
|
||||
works for Swift projects without any modification). If you are building manually, you can use ``-F`` and
|
||||
``-framework mujoco`` to specify the header search path and the library search path respectively. The macOS Makefile
|
||||
provides an example for this.
|
||||
|
||||
.. _inBuild:
|
||||
|
||||
Building MuJoCo from source
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To build MuJoCo from source, you will need CMake and a working C++17 compiler installed. The steps are:
|
||||
|
||||
#. Clone the ``mujoco`` repository from GitHub.
|
||||
#. Create a new build directory somewhere, and ``cd`` into it.
|
||||
#. Run ``cmake $PATH_TO_CLONED_REPO`` to configure the build.
|
||||
#. Run ``cmake --build .`` to build.
|
||||
|
||||
MuJoCo's build system automatically fetches dependencies from upstream repositories over the Internet using CMake's
|
||||
`FetchContent <https://cmake.org/cmake/help/latest/module/FetchContent.html>`_ module.
|
||||
|
||||
The main CMake setup will build the MuJoCo library itself along with all sample applications, but the Python
|
||||
bindings are not built. Those come with their own build instructions, which can be found in the :doc:`python`
|
||||
section of the documentation.
|
||||
|
||||
Additionally, the CMake setup also implements an installation phase which will copy and organize the output files to a
|
||||
target directory. Specify the directory using ``cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=<my_install_dir>``.
|
||||
After successfully building MuJoCo following the instructions above, you can install it using ``cmake --install .``.
|
||||
|
||||
.. _inHeader:
|
||||
|
||||
@@ -100,29 +126,29 @@ Header files
|
||||
The distribution contains several header files which are identical on all platforms. They are also available from the
|
||||
links below, to make this documentation self-contained.
|
||||
|
||||
mujoco.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco.h>`__
|
||||
mujoco.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mujoco.h>`__
|
||||
This is the main header file and must be included in all programs using MuJoCo. It defines all API functions and
|
||||
global variables, and includes the next 5 files which provide the necessary type definitions.
|
||||
mjmodel.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`__
|
||||
mjmodel.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`__
|
||||
This file defines the C structure :ref:`mjModel` which is the runtime representation of the
|
||||
model being simulated. It also defines a number of primitive types and other structures needed to define mjModel.
|
||||
mjdata.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`__
|
||||
mjdata.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`__
|
||||
This file defines the C structure :ref:`mjData` which is the workspace where all computations
|
||||
read their inputs and write their outputs. It also defines primitive types and other structures needed to define
|
||||
mjData.
|
||||
mjvisualize.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`__
|
||||
mjvisualize.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`__
|
||||
This file defines the primitive types and structures needed by the abstract visualizer.
|
||||
mjrender.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`__
|
||||
mjrender.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`__
|
||||
This file defines the primitive types and structures needed by the OpenGL renderer.
|
||||
mjui.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`__
|
||||
mjui.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`__
|
||||
This file defines the primitive types and structures needed by the UI framework.
|
||||
mjtnum.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`__
|
||||
mjtnum.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`__
|
||||
Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`.
|
||||
mjxmacro.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjxmacro.h>`__
|
||||
mjxmacro.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`__
|
||||
This file is optional and is not included by mujoco.h. It defines :ref:`X Macros <tyXMacro>` that can
|
||||
automate the mapping of mjModel and mjData into scripting languages, as well as other operations that require
|
||||
accessing all fields of mjModel and mjData. See code sample :ref:`testxml.cc <saTestXML>`.
|
||||
mjexport.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjexport.h>`__
|
||||
mjexport.h `(source) <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjexport.h>`__
|
||||
Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client
|
||||
code.
|
||||
glfw3.h
|
||||
@@ -152,7 +178,7 @@ the symbol :ref:`mjVERSION_HEADER <glNumeric>` and the library provides the func
|
||||
|
||||
// recommended version check
|
||||
if( mjVERSION_HEADER!=mj_version() )
|
||||
complain();
|
||||
complain();
|
||||
|
||||
Note that only the main header defines this symbol. We assume that the collection of headers released with each software
|
||||
version will stay together and will not be mixed between versions. To avoid complications with floating-point
|
||||
@@ -309,7 +335,10 @@ This code sample is a full-featured interactive simulator. It opens an OpenGL wi
|
||||
GLFW library, and renders the simulation state in it. There is built-in help, simulation statistics, profiler, sensor
|
||||
data plots. The model file can be specified as a command-line argument, or loaded at runtime using drag-and-drop
|
||||
functionality. As of MuJoCo 2.0, this code sample uses the native UI to render various controls, and provides an
|
||||
illustration of how the new UI framework is intended to be used.
|
||||
illustration of how the new UI framework is intended to be used. Below is a screen-capture of ``simulate`` in action:
|
||||
|
||||
.. youtube:: 0ORsj_E17B0
|
||||
:align: center
|
||||
|
||||
Interaction is done with the mouse; see the built-in help for summary of available commands. Briefly, an object is
|
||||
selected by left-double-click. The user can then apply forces and torques on the selected object by holding Ctrl and
|
||||
@@ -556,7 +585,7 @@ function :ref:`mj_step` in a loop such as
|
||||
|
||||
// simulate until t = 10 seconds
|
||||
while( d->time<10 )
|
||||
mj_step(m, d);
|
||||
mj_step(m, d);
|
||||
|
||||
This by itself will simulate the passive dynamics, because we have not provided any control signals or applied forces.
|
||||
The default (and recommended) way to control the system is to implement a control callback, for example
|
||||
@@ -566,8 +595,8 @@ The default (and recommended) way to control the system is to implement a contro
|
||||
// simple controller applying damping to each dof
|
||||
void mycontroller(const mjModel* m, mjData* d)
|
||||
{
|
||||
if( m->nu==m->nv )
|
||||
mju_scl(d->ctrl, d->qvel, -0.1, m->nv);
|
||||
if( m->nu==m->nv )
|
||||
mju_scl(d->ctrl, d->qvel, -0.1, m->nv);
|
||||
}
|
||||
|
||||
This illustrates two concepts. First, we are checking if the number of controls ``mjModel.nu`` equals the number of
|
||||
@@ -595,10 +624,9 @@ control callback) would become
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
while( d->time<10 )
|
||||
{
|
||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||
mj_step(m, d);
|
||||
while( d->time<10 ) {
|
||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||
mj_step(m, d);
|
||||
}
|
||||
|
||||
Why would we not be able to compute the controls before ``mj_step`` is called? After all, isn't this what causality means?
|
||||
@@ -619,11 +647,10 @@ before the control is needed, and after the control is needed. The simulation lo
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
while( d->time<10 )
|
||||
{
|
||||
mj_step1(m, d);
|
||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||
mj_step2(m, d);
|
||||
while( d->time<10 ) {
|
||||
mj_step1(m, d);
|
||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||
mj_step2(m, d);
|
||||
}
|
||||
|
||||
There is one complication however: this only works with Euler integration. The Runge-Kutta integrator (as well as other
|
||||
@@ -637,23 +664,22 @@ omitting some code that computes timing diagnostics. The main simulation functio
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void mj_step(const mjModel* m, mjData* d)
|
||||
{
|
||||
// common to all integrators
|
||||
mj_checkPos(m, d);
|
||||
mj_checkVel(m, d);
|
||||
mj_forward(m, d);
|
||||
mj_checkAcc(m, d);
|
||||
void mj_step(const mjModel* m, mjData* d) {
|
||||
// common to all integrators
|
||||
mj_checkPos(m, d);
|
||||
mj_checkVel(m, d);
|
||||
mj_forward(m, d);
|
||||
mj_checkAcc(m, d);
|
||||
|
||||
// compare forward and inverse solutions if enabled
|
||||
if( mjENABLED(mjENBL_FWDINV) )
|
||||
mj_compareFwdInv(m, d);
|
||||
// compare forward and inverse solutions if enabled
|
||||
if( mjENABLED(mjENBL_FWDINV) )
|
||||
mj_compareFwdInv(m, d);
|
||||
|
||||
// use selected integrator
|
||||
if( m->opt.integrator==mjINT_RK4 )
|
||||
mj_RungeKutta(m, d, 4);
|
||||
else
|
||||
mj_Euler(m, d);
|
||||
// use selected integrator
|
||||
if( m->opt.integrator==mjINT_RK4 )
|
||||
mj_RungeKutta(m, d, 4);
|
||||
else
|
||||
mj_Euler(m, d);
|
||||
}
|
||||
|
||||
The checking functions reset the simulation automatically if any numerical values have become invalid or too large.
|
||||
@@ -668,34 +694,34 @@ mj_step2 regardless of the setting of ``mjModel.opt.integrator``.
|
||||
|
||||
void mj_step1(const mjModel* m, mjData* d)
|
||||
{
|
||||
mj_checkPos(m, d);
|
||||
mj_checkVel(m, d);
|
||||
mj_fwdPosition(m, d);
|
||||
mj_sensorPos(m, d);
|
||||
mj_energyPos(m, d);
|
||||
mj_fwdVelocity(m, d);
|
||||
mj_sensorVel(m, d);
|
||||
mj_energyVel(m, d);
|
||||
mj_checkPos(m, d);
|
||||
mj_checkVel(m, d);
|
||||
mj_fwdPosition(m, d);
|
||||
mj_sensorPos(m, d);
|
||||
mj_energyPos(m, d);
|
||||
mj_fwdVelocity(m, d);
|
||||
mj_sensorVel(m, d);
|
||||
mj_energyVel(m, d);
|
||||
|
||||
// if we had a callback we would be using mj_step, but call it anyway
|
||||
if( mjcb_control )
|
||||
mjcb_control(m, d);
|
||||
// if we had a callback we would be using mj_step, but call it anyway
|
||||
if( mjcb_control )
|
||||
mjcb_control(m, d);
|
||||
}
|
||||
|
||||
void mj_step2(const mjModel* m, mjData* d)
|
||||
{
|
||||
mj_fwdActuation(m, d);
|
||||
mj_fwdAcceleration(m, d);
|
||||
mj_fwdConstraint(m, d);
|
||||
mj_sensorAcc(m, d);
|
||||
mj_checkAcc(m, d);
|
||||
mj_fwdActuation(m, d);
|
||||
mj_fwdAcceleration(m, d);
|
||||
mj_fwdConstraint(m, d);
|
||||
mj_sensorAcc(m, d);
|
||||
mj_checkAcc(m, d);
|
||||
|
||||
// compare forward and inverse solutions if enabled
|
||||
if( mjENABLED(mjENBL_FWDINV) )
|
||||
mj_compareFwdInv(m, d);
|
||||
// compare forward and inverse solutions if enabled
|
||||
if( mjENABLED(mjENBL_FWDINV) )
|
||||
mj_compareFwdInv(m, d);
|
||||
|
||||
// integrate with Euler; ignore integrator option
|
||||
mj_Euler(m, d);
|
||||
// integrate with Euler; ignore integrator option
|
||||
mj_Euler(m, d);
|
||||
}
|
||||
|
||||
.. _siStateControl:
|
||||
@@ -830,37 +856,35 @@ skip arguments (mjSTAGE_NONE, 0), where the latter function is implemented as
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void mj_forwardSkip(const mjModel* m, mjData* d,
|
||||
int skipstage, int skipsensor)
|
||||
{
|
||||
// position-dependent
|
||||
if( skipstage<mjSTAGE_POS )
|
||||
{
|
||||
mj_fwdPosition(m, d);
|
||||
if( !skipsensor )
|
||||
mj_sensorPos(m, d);
|
||||
if( mjENABLED(mjENBL_ENERGY) )
|
||||
mj_energyPos(m, d);
|
||||
}
|
||||
|
||||
// velocity-dependent
|
||||
if( skipstage<mjSTAGE_VEL )
|
||||
{
|
||||
mj_fwdVelocity(m, d);
|
||||
if( !skipsensor )
|
||||
mj_sensorVel(m, d);
|
||||
if( mjENABLED(mjENBL_ENERGY) )
|
||||
mj_energyVel(m, d);
|
||||
}
|
||||
|
||||
// acceleration-dependent
|
||||
if( mjcb_control )
|
||||
mjcb_control(m, d);
|
||||
mj_fwdActuation(m, d);
|
||||
mj_fwdAcceleration(m, d);
|
||||
mj_fwdConstraint(m, d);
|
||||
void mj_forwardSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor) {
|
||||
// position-dependent
|
||||
if( skipstage<mjSTAGE_POS )
|
||||
{
|
||||
mj_fwdPosition(m, d);
|
||||
if( !skipsensor )
|
||||
mj_sensorAcc(m, d);
|
||||
mj_sensorPos(m, d);
|
||||
if( mjENABLED(mjENBL_ENERGY) )
|
||||
mj_energyPos(m, d);
|
||||
}
|
||||
|
||||
// velocity-dependent
|
||||
if( skipstage<mjSTAGE_VEL )
|
||||
{
|
||||
mj_fwdVelocity(m, d);
|
||||
if( !skipsensor )
|
||||
mj_sensorVel(m, d);
|
||||
if( mjENABLED(mjENBL_ENERGY) )
|
||||
mj_energyVel(m, d);
|
||||
}
|
||||
|
||||
// acceleration-dependent
|
||||
if( mjcb_control )
|
||||
mjcb_control(m, d);
|
||||
mj_fwdActuation(m, d);
|
||||
mj_fwdAcceleration(m, d);
|
||||
mj_fwdConstraint(m, d);
|
||||
if( !skipsensor )
|
||||
mj_sensorAcc(m, d);
|
||||
}
|
||||
|
||||
Note that this is the same sequence of calls as in mj_step1 and mj_step2 above, except that checking of real values
|
||||
@@ -985,17 +1009,17 @@ management.
|
||||
// parallel section
|
||||
#pragma omp parallel
|
||||
{
|
||||
int n = omp_get_thread_num(); // thread-private variable with thread id (0 to nthread-1)
|
||||
int n = omp_get_thread_num(); // thread-private variable with thread id (0 to nthread-1)
|
||||
|
||||
// ... initialize d[n] from results in serial code
|
||||
// ... initialize d[n] from results in serial code
|
||||
|
||||
// thread function
|
||||
worker(m, d[n]); // shared mjModel (read-only), per-thread mjData (read-write)
|
||||
// thread function
|
||||
worker(m, d[n]); // shared mjModel (read-only), per-thread mjData (read-write)
|
||||
}
|
||||
|
||||
// delete per-thread mjData
|
||||
for( int n=0; n<nthread; n++ )
|
||||
mj_deleteData(d[n]);
|
||||
mj_deleteData(d[n]);
|
||||
|
||||
Since all top-level API functions threat mjModel as ``const``, this multi-threading scheme is safe. Each thread only
|
||||
writes to its own mjData. Therefore no further synchronization among threads is needed.
|
||||
@@ -1310,11 +1334,11 @@ the total energy indicate inaccuracies in numerical integration. For such system
|
||||
better performance than the default semi-implicit Euler integrator.
|
||||
|
||||
Finally, the user can implement additional diagnostics as needed. Two examples were provided in the code samples
|
||||
``testxml.cc`` and ``derivative.cc``, where we computed model mismatches after save and load, and assessed the accuracy of the
|
||||
numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or simulation
|
||||
paths that compute the same quantity, and compare the results numerically. This type of sanity check is essential when
|
||||
dealing with complex dynamical systems where we do not really know what the numerical output should be; if we knew
|
||||
that, we would not be using a simulator in the first place.
|
||||
``testxml.cc`` and ``derivative.cc``, where we computed model mismatches after save and load, and assessed the accuracy
|
||||
of the numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or
|
||||
simulation paths that compute the same quantity, and compare the results numerically. This type of sanity check is
|
||||
essential when dealing with complex dynamical systems where we do not really know what the numerical output should be;
|
||||
if we knew that, we would not be using a simulator in the first place.
|
||||
|
||||
.. _siJacobian:
|
||||
|
||||
@@ -1529,29 +1553,28 @@ one of its derivatives.
|
||||
// ... install GLFW keyboard and mouse callbacks
|
||||
|
||||
// run main loop, target real-time simulation and 60 fps rendering
|
||||
while( !glfwWindowShouldClose(window) )
|
||||
{
|
||||
// advance interactive simulation for 1/60 sec
|
||||
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
|
||||
// this loop will finish on time for the next frame to be rendered at 60 fps.
|
||||
// Otherwise add a cpu timer and exit this loop when it is time to render.
|
||||
mjtNum simstart = d->time;
|
||||
while( d->time - simstart < 1.0/60.0 )
|
||||
mj_step(m, d);
|
||||
while( !glfwWindowShouldClose(window) ) {
|
||||
// advance interactive simulation for 1/60 sec
|
||||
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
|
||||
// this loop will finish on time for the next frame to be rendered at 60 fps.
|
||||
// Otherwise add a cpu timer and exit this loop when it is time to render.
|
||||
mjtNum simstart = d->time;
|
||||
while( d->time - simstart < 1.0/60.0 )
|
||||
mj_step(m, d);
|
||||
|
||||
// get framebuffer viewport
|
||||
mjrRect viewport = {0, 0, 0, 0};
|
||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||
// get framebuffer viewport
|
||||
mjrRect viewport = {0, 0, 0, 0};
|
||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||
|
||||
// update scene and render
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
mjr_render(viewport, &scn, &con);
|
||||
// update scene and render
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
mjr_render(viewport, &scn, &con);
|
||||
|
||||
// swap OpenGL buffers (blocking call due to v-sync)
|
||||
glfwSwapBuffers(window);
|
||||
// swap OpenGL buffers (blocking call due to v-sync)
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// process pending GUI events, call GLFW callbacks
|
||||
glfwPollEvents();
|
||||
// process pending GUI events, call GLFW callbacks
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// close GLFW, free visualization storage
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
Python Bindings
|
||||
===============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Starting with version 2.1.2, MuJoCo comes with native Python bindings that are developed in C++ using
|
||||
`pybind11 <https://pybind11.readthedocs.io/>`__. Unlike previous Python bindings, these are officially supported by the
|
||||
MuJoCo development team and will be kept up-to-date with the latest developments in MuJoCo itself.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
sphinx==3.5.4
|
||||
sphinx_rtd_theme==0.5.2
|
||||
sphinxcontrib-katex==0.8.6
|
||||
sphinxcontrib-youtube==1.1.0
|
||||
sphinx-reredirects==0.0.1
|
||||
nbsphinx==0.8.0
|
||||
pandoc==1.0.2
|
||||
|
||||
+2
-2
@@ -29,14 +29,14 @@ _____
|
||||
|
||||
The MuJoCo app needs to be run at least once before the native library can be used, in order to register the library as
|
||||
a trusted binary. Then, copy the dynamic library file from
|
||||
``/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.framework/Versions/Current/libmujoco.2.1.5.dylib`` (it can be
|
||||
``/Applications/MuJoCo.app/Contents/Frameworks/mujoco.framework/Versions/Current/libmujoco.2.2.0.dylib`` (it can be
|
||||
found by browsing the contents of ``MuJoCo.app``) and rename it as ``mujoco.dylib``.
|
||||
|
||||
Linux
|
||||
_____
|
||||
|
||||
Expand the ``tar.gz`` archive to ``~/.mujoco``. Then copy the dynamic library from
|
||||
``~/.mujoco/mujoco-2.1.5/lib/libmujoco.so.2.1.5`` and rename it as ``libmujoco.so``.
|
||||
``~/.mujoco/mujoco-2.2.0/lib/libmujoco.so.2.2.0`` and rename it as ``libmujoco.so``.
|
||||
|
||||
Windows
|
||||
_______
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#ifndef MUJOCO_MJDATA_H_
|
||||
#define MUJOCO_MJDATA_H_
|
||||
|
||||
#include <mjtnum.h>
|
||||
#include <mjmodel.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||
|
||||
@@ -293,11 +293,11 @@ struct mjData_ {
|
||||
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||
|
||||
// computed by mj_fwdAcceleration
|
||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
||||
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_smooth; // unconstrained acceleration (nv x 1)
|
||||
|
||||
// computed by mj_fwdConstraint/mj_inverse
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (njmax x 1)
|
||||
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef MUJOCO_MJMODEL_H_
|
||||
#define MUJOCO_MJMODEL_H_
|
||||
|
||||
#include <mjtnum.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
|
||||
// global constants
|
||||
#define mjPI 3.14159265358979323846
|
||||
@@ -68,9 +68,8 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags
|
||||
mjENBL_ENERGY = 1<<1, // energy computation
|
||||
mjENBL_FWDINV = 1<<2, // record solver statistics
|
||||
mjENBL_SENSORNOISE = 1<<3, // add noise to sensor data
|
||||
|
||||
// experimental features:
|
||||
mjENBL_MULTICCD = 1<<30, // multi-point convex collision detection
|
||||
mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection
|
||||
|
||||
mjNENABLE = 5 // number of enable flags
|
||||
} mjtEnableBit;
|
||||
@@ -833,11 +832,13 @@ struct mjModel_ {
|
||||
int* actuator_group; // group for visibility (nu x 1)
|
||||
mjtByte* actuator_ctrllimited; // is control limited (nu x 1)
|
||||
mjtByte* actuator_forcelimited;// is force limited (nu x 1)
|
||||
mjtByte* actuator_actlimited; // is activation limited (nu x 1)
|
||||
mjtNum* actuator_dynprm; // dynamics parameters (nu x mjNDYN)
|
||||
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
|
||||
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
|
||||
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
|
||||
mjtNum* actuator_forcerange; // range of forces (nu x 2)
|
||||
mjtNum* actuator_actrange; // range of activations (nu x 2)
|
||||
mjtNum* actuator_gear; // scale length and transmitted force (nu x 6)
|
||||
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
|
||||
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef MUJOCO_MJRENDER_H_
|
||||
#define MUJOCO_MJRENDER_H_
|
||||
|
||||
#include <mjmodel.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef MUJOCO_MJUI_H_
|
||||
#define MUJOCO_MJUI_H_
|
||||
|
||||
#include <mjrender.h>
|
||||
#include <mujoco/mjrender.h>
|
||||
|
||||
#define mjMAXUISECT 10 // maximum number of sections
|
||||
#define mjMAXUIITEM 80 // maximum number of items per section
|
||||
@@ -15,8 +15,8 @@
|
||||
#ifndef MUJOCO_MJVISUALIZE_H_
|
||||
#define MUJOCO_MJVISUALIZE_H_
|
||||
|
||||
#include <mjtnum.h>
|
||||
#include <mjmodel.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
|
||||
#define mjMAXLIGHT 100 // maximum number of lights in a scene
|
||||
@@ -20,28 +20,28 @@
|
||||
|
||||
// scalar fields of mjOption
|
||||
#define MJOPTION_FLOATS \
|
||||
X( mjtNum, timestep ) \
|
||||
X( mjtNum, apirate ) \
|
||||
X( mjtNum, impratio ) \
|
||||
X( mjtNum, tolerance ) \
|
||||
X( mjtNum, timestep ) \
|
||||
X( mjtNum, apirate ) \
|
||||
X( mjtNum, impratio ) \
|
||||
X( mjtNum, tolerance ) \
|
||||
X( mjtNum, noslip_tolerance ) \
|
||||
X( mjtNum, mpr_tolerance ) \
|
||||
X( mjtNum, density ) \
|
||||
X( mjtNum, viscosity ) \
|
||||
X( mjtNum, o_margin ) \
|
||||
X( mjtNum, mpr_tolerance ) \
|
||||
X( mjtNum, density ) \
|
||||
X( mjtNum, viscosity ) \
|
||||
X( mjtNum, o_margin ) \
|
||||
|
||||
|
||||
#define MJOPTION_INTS \
|
||||
X( int, integrator ) \
|
||||
X( int, collision ) \
|
||||
X( int, cone ) \
|
||||
X( int, jacobian ) \
|
||||
X( int, solver ) \
|
||||
X( int, iterations ) \
|
||||
X( int, integrator ) \
|
||||
X( int, collision ) \
|
||||
X( int, cone ) \
|
||||
X( int, jacobian ) \
|
||||
X( int, solver ) \
|
||||
X( int, iterations ) \
|
||||
X( int, noslip_iterations ) \
|
||||
X( int, mpr_iterations ) \
|
||||
X( int, disableflags ) \
|
||||
X( int, enableflags )
|
||||
X( int, mpr_iterations ) \
|
||||
X( int, disableflags ) \
|
||||
X( int, enableflags )
|
||||
|
||||
|
||||
#define MJOPTION_SCALARS \
|
||||
@@ -351,11 +351,13 @@
|
||||
X( int, actuator_group, nu, 1 ) \
|
||||
X( mjtByte, actuator_ctrllimited, nu, 1 ) \
|
||||
X( mjtByte, actuator_forcelimited, nu, 1 ) \
|
||||
X( mjtByte, actuator_actlimited, nu, 1 ) \
|
||||
X( mjtNum, actuator_dynprm, nu, mjNDYN ) \
|
||||
X( mjtNum, actuator_gainprm, nu, mjNGAIN ) \
|
||||
X( mjtNum, actuator_biasprm, nu, mjNBIAS ) \
|
||||
X( mjtNum, actuator_ctrlrange, nu, 2 ) \
|
||||
X( mjtNum, actuator_forcerange, nu, 2 ) \
|
||||
X( mjtNum, actuator_actrange, nu, 2 ) \
|
||||
X( mjtNum, actuator_gear, nu, 6 ) \
|
||||
X( mjtNum, actuator_cranklength, nu, 1 ) \
|
||||
X( mjtNum, actuator_acc0, nu, 1 ) \
|
||||
@@ -508,8 +510,8 @@
|
||||
X( mjtNum, subtree_angmom, nbody, 3 ) \
|
||||
X( mjtNum, actuator_force, nu, 1 ) \
|
||||
X( mjtNum, qfrc_actuator, nv, 1 ) \
|
||||
X( mjtNum, qfrc_unc, nv, 1 ) \
|
||||
X( mjtNum, qacc_unc, nv, 1 ) \
|
||||
X( mjtNum, qfrc_smooth, nv, 1 ) \
|
||||
X( mjtNum, qacc_smooth, nv, 1 ) \
|
||||
X( mjtNum, efc_b, njmax, 1 ) \
|
||||
X( mjtNum, efc_force, njmax, 1 ) \
|
||||
X( int, efc_state, njmax, 1 ) \
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef MUJOCO_MUJOCO_H_
|
||||
#define MUJOCO_MUJOCO_H_
|
||||
|
||||
#include <mjexport.h>
|
||||
#include <mujoco/mjexport.h>
|
||||
|
||||
|
||||
// this is a C-API
|
||||
@@ -24,7 +24,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// header version; should match the library version as returned by mj_version()
|
||||
#define mjVERSION_HEADER 215
|
||||
#define mjVERSION_HEADER 220
|
||||
|
||||
// needed to define size_t, fabs and log10
|
||||
#include "stdlib.h"
|
||||
@@ -32,12 +32,12 @@ extern "C" {
|
||||
|
||||
|
||||
// type definitions
|
||||
#include <mjdata.h>
|
||||
#include <mjmodel.h>
|
||||
#include <mjrender.h>
|
||||
#include <mjtnum.h>
|
||||
#include <mjui.h>
|
||||
#include <mjvisualize.h>
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjrender.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjui.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
|
||||
|
||||
// macros
|
||||
@@ -139,12 +139,10 @@ MJAPI void mj_forward(const mjModel* m, mjData* d);
|
||||
MJAPI void mj_inverse(const mjModel* m, mjData* d);
|
||||
|
||||
// Forward dynamics with skip; skipstage is mjtStage.
|
||||
MJAPI void mj_forwardSkip(const mjModel* m, mjData* d,
|
||||
int skipstage, int skipsensor);
|
||||
MJAPI void mj_forwardSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor);
|
||||
|
||||
// Inverse dynamics with skip; skipstage is mjtStage.
|
||||
MJAPI void mj_inverseSkip(const mjModel* m, mjData* d,
|
||||
int skipstage, int skipsensor);
|
||||
MJAPI void mj_inverseSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor);
|
||||
|
||||
|
||||
//---------------------------------- Initialization ------------------------------------------------
|
||||
@@ -215,8 +213,7 @@ MJAPI int mj_setLengthRange(mjModel* m, mjData* d, int index,
|
||||
|
||||
// Print mjModel to text file, specifying format.
|
||||
// float_format must be a valid printf-style format string for a single float value.
|
||||
MJAPI void mj_printFormattedModel(const mjModel* m, const char* filename,
|
||||
const char* float_format);
|
||||
MJAPI void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format);
|
||||
|
||||
// Print model to text file.
|
||||
MJAPI void mj_printModel(const mjModel* m, const char* filename);
|
||||
@@ -234,8 +231,7 @@ MJAPI void mju_printMat(const mjtNum* mat, int nr, int nc);
|
||||
|
||||
// Print sparse matrix to screen.
|
||||
MJAPI void mju_printMatSparse(const mjtNum* mat, int nr,
|
||||
const int* rownnz, const int* rowadr,
|
||||
const int* colind);
|
||||
const int* rownnz, const int* rowadr, const int* colind);
|
||||
|
||||
|
||||
//---------------------------------- Components ----------------------------------------------------
|
||||
@@ -246,7 +242,7 @@ MJAPI void mj_fwdPosition(const mjModel* m, mjData* d);
|
||||
// Run velocity-dependent computations.
|
||||
MJAPI void mj_fwdVelocity(const mjModel* m, mjData* d);
|
||||
|
||||
// Compute actuator force qfrc_actuation.
|
||||
// Compute actuator force qfrc_actuator.
|
||||
MJAPI void mj_fwdActuation(const mjModel* m, mjData* d);
|
||||
|
||||
// Add up all non-constraint forces, compute qacc_unc.
|
||||
@@ -375,35 +371,29 @@ MJAPI int mj_isSparse(const mjModel* m);
|
||||
MJAPI int mj_isDual(const mjModel* m);
|
||||
|
||||
// Multiply dense or sparse constraint Jacobian by vector.
|
||||
MJAPI void mj_mulJacVec(const mjModel* m, mjData* d,
|
||||
mjtNum* res, const mjtNum* vec);
|
||||
MJAPI void mj_mulJacVec(const mjModel* m, mjData* d, mjtNum* res, const mjtNum* vec);
|
||||
|
||||
// Multiply dense or sparse constraint Jacobian transpose by vector.
|
||||
MJAPI void mj_mulJacTVec(const mjModel* m, mjData* d, mjtNum* res, const mjtNum* vec);
|
||||
|
||||
// Compute 3/6-by-nv end-effector Jacobian of global point attached to given body.
|
||||
MJAPI void mj_jac(const mjModel* m, const mjData* d,
|
||||
mjtNum* jacp, mjtNum* jacr, const mjtNum point[3], int body);
|
||||
MJAPI void mj_jac(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr,
|
||||
const mjtNum point[3], int body);
|
||||
|
||||
// Compute body frame end-effector Jacobian.
|
||||
MJAPI void mj_jacBody(const mjModel* m, const mjData* d,
|
||||
mjtNum* jacp, mjtNum* jacr, int body);
|
||||
MJAPI void mj_jacBody(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int body);
|
||||
|
||||
// Compute body center-of-mass end-effector Jacobian.
|
||||
MJAPI void mj_jacBodyCom(const mjModel* m, const mjData* d,
|
||||
mjtNum* jacp, mjtNum* jacr, int body);
|
||||
MJAPI void mj_jacBodyCom(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int body);
|
||||
|
||||
// Compute geom end-effector Jacobian.
|
||||
MJAPI void mj_jacGeom(const mjModel* m, const mjData* d,
|
||||
mjtNum* jacp, mjtNum* jacr, int geom);
|
||||
MJAPI void mj_jacGeom(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int geom);
|
||||
|
||||
// Compute site end-effector Jacobian.
|
||||
MJAPI void mj_jacSite(const mjModel* m, const mjData* d,
|
||||
mjtNum* jacp, mjtNum* jacr, int site);
|
||||
MJAPI void mj_jacSite(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int site);
|
||||
|
||||
// Compute translation end-effector Jacobian of point, and rotation Jacobian of axis.
|
||||
MJAPI void mj_jacPointAxis(const mjModel* m, mjData* d,
|
||||
mjtNum* jacPoint, mjtNum* jacAxis,
|
||||
MJAPI void mj_jacPointAxis(const mjModel* m, mjData* d, mjtNum* jacPoint, mjtNum* jacAxis,
|
||||
const mjtNum point[3], const mjtNum axis[3], int body);
|
||||
|
||||
// Get id of object with specified name, return -1 if not found; type is mjtObj.
|
||||
@@ -423,12 +413,10 @@ MJAPI void mj_mulM2(const mjModel* m, const mjData* d, mjtNum* res, const mjtNum
|
||||
|
||||
// Add inertia matrix to destination matrix.
|
||||
// Destination can be sparse uncompressed, or dense when all int* are NULL
|
||||
MJAPI void mj_addM(const mjModel* m, mjData* d, mjtNum* dst,
|
||||
int* rownnz, int* rowadr, int* colind);
|
||||
MJAPI void mj_addM(const mjModel* m, mjData* d, mjtNum* dst, int* rownnz, int* rowadr, int* colind);
|
||||
|
||||
// Apply cartesian force and torque (outside xfrc_applied mechanism).
|
||||
MJAPI void mj_applyFT(const mjModel* m, mjData* d,
|
||||
const mjtNum force[3], const mjtNum torque[3],
|
||||
MJAPI void mj_applyFT(const mjModel* m, mjData* d, const mjtNum force[3], const mjtNum torque[3],
|
||||
const mjtNum point[3], int body, mjtNum* qfrc_target);
|
||||
|
||||
// Compute object 6D velocity in object-centered frame, world/local orientation.
|
||||
@@ -453,9 +441,8 @@ MJAPI void mj_integratePos(const mjModel* m, mjtNum* qpos, const mjtNum* qvel, m
|
||||
MJAPI void mj_normalizeQuat(const mjModel* m, mjtNum* qpos);
|
||||
|
||||
// Map from body local to global Cartesian coordinates.
|
||||
MJAPI void mj_local2Global(mjData* d, mjtNum xpos[3], mjtNum xmat[9],
|
||||
const mjtNum pos[3], const mjtNum quat[4],
|
||||
int body, mjtByte sameframe);
|
||||
MJAPI void mj_local2Global(mjData* d, mjtNum xpos[3], mjtNum xmat[9], const mjtNum pos[3],
|
||||
const mjtNum quat[4], int body, mjtByte sameframe);
|
||||
|
||||
// Sum all body masses.
|
||||
MJAPI mjtNum mj_getTotalmass(const mjModel* m);
|
||||
@@ -657,8 +644,7 @@ MJAPI void mjr_blitBuffer(mjrRect src, mjrRect dst,
|
||||
MJAPI void mjr_setAux(int index, const mjrContext* con);
|
||||
|
||||
// Blit from Aux buffer to con->currentBuffer.
|
||||
MJAPI void mjr_blitAux(int index, mjrRect src, int left, int bottom,
|
||||
const mjrContext* con);
|
||||
MJAPI void mjr_blitAux(int index, mjrRect src, int left, int bottom, const mjrContext* con);
|
||||
|
||||
// Draw text at (x,y) in relative coordinates; font is mjtFont.
|
||||
MJAPI void mjr_text(int font, const char* txt, const mjrContext* con,
|
||||
@@ -914,12 +900,10 @@ MJAPI mjtNum mju_norm(const mjtNum* res, int n);
|
||||
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n);
|
||||
|
||||
// Multiply matrix and vector: res = mat * vec.
|
||||
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec,
|
||||
int nr, int nc);
|
||||
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||
|
||||
// Multiply transposed matrix and vector: res = mat' * vec.
|
||||
MJAPI void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec,
|
||||
int nr, int nc);
|
||||
MJAPI void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||
|
||||
// Transpose matrix: res = mat'.
|
||||
MJAPI void mju_transpose(mjtNum* res, const mjtNum* mat, int nr, int nc);
|
||||
@@ -954,10 +938,10 @@ MJAPI void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[
|
||||
// Conjugate quaternion, corresponding to opposite rotation.
|
||||
MJAPI void mju_negQuat(mjtNum res[4], const mjtNum quat[4]);
|
||||
|
||||
// Muiltiply quaternions.
|
||||
// Multiply quaternions.
|
||||
MJAPI void mju_mulQuat(mjtNum res[4], const mjtNum quat1[4], const mjtNum quat2[4]);
|
||||
|
||||
// Muiltiply quaternion and axis.
|
||||
// Multiply quaternion and axis.
|
||||
MJAPI void mju_mulQuatAxis(mjtNum res[4], const mjtNum quat[4], const mjtNum axis[3]);
|
||||
|
||||
// Convert axisAngle to quaternion.
|
||||
@@ -1030,12 +1014,10 @@ MJAPI mjtNum mju_muscleBias(mjtNum len, const mjtNum lengthrange[2],
|
||||
MJAPI mjtNum mju_muscleDynamics(mjtNum ctrl, mjtNum act, const mjtNum prm[2]);
|
||||
|
||||
// Convert contact force to pyramid representation.
|
||||
MJAPI void mju_encodePyramid(mjtNum* pyramid, const mjtNum* force,
|
||||
const mjtNum* mu, int dim);
|
||||
MJAPI void mju_encodePyramid(mjtNum* pyramid, const mjtNum* force, const mjtNum* mu, int dim);
|
||||
|
||||
// Convert pyramid representation to contact force.
|
||||
MJAPI void mju_decodePyramid(mjtNum* force, const mjtNum* pyramid,
|
||||
const mjtNum* mu, int dim);
|
||||
MJAPI void mju_decodePyramid(mjtNum* force, const mjtNum* pyramid, const mjtNum* mu, int dim);
|
||||
|
||||
// Integrate spring-damper analytically, return pos(dt).
|
||||
MJAPI mjtNum mju_springDamper(mjtNum pos0, mjtNum vel0, mjtNum Kp, mjtNum Kv, mjtNum dt);
|
||||
+1
-1
@@ -51,7 +51,7 @@ ENUMS: Mapping[str, EnumDecl] = dict([
|
||||
('mjENBL_ENERGY', 2),
|
||||
('mjENBL_FWDINV', 4),
|
||||
('mjENBL_SENSORNOISE', 8),
|
||||
('mjENBL_MULTICCD', 1073741824),
|
||||
('mjENBL_MULTICCD', 16),
|
||||
('mjNENABLE', 5),
|
||||
]),
|
||||
)),
|
||||
|
||||
@@ -42,7 +42,7 @@ class EnumsTest(absltest.TestCase):
|
||||
('mjENBL_ENERGY', 1<<1),
|
||||
('mjENBL_FWDINV', 1<<2),
|
||||
('mjENBL_SENSORNOISE', 1<<3),
|
||||
('mjENBL_MULTICCD', 1<<30),
|
||||
('mjENBL_MULTICCD', 1<<4),
|
||||
('mjNENABLE', 5)))
|
||||
|
||||
# values mostly increment by one with occasional overrides
|
||||
|
||||
@@ -998,7 +998,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
||||
),
|
||||
),
|
||||
),
|
||||
doc='Compute actuator force qfrc_actuation.',
|
||||
doc='Compute actuator force qfrc_actuator.',
|
||||
)),
|
||||
('mj_fwdAcceleration',
|
||||
FunctionDecl(
|
||||
@@ -5895,7 +5895,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
||||
),
|
||||
),
|
||||
),
|
||||
doc='Muiltiply quaternions.',
|
||||
doc='Multiply quaternions.',
|
||||
)),
|
||||
('mju_mulQuatAxis',
|
||||
FunctionDecl(
|
||||
@@ -5924,7 +5924,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
||||
),
|
||||
),
|
||||
),
|
||||
doc='Muiltiply quaternion and axis.',
|
||||
doc='Multiply quaternion and axis.',
|
||||
)),
|
||||
('mju_axisAngle2Quat',
|
||||
FunctionDecl(
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Copy the model files to the binary directory to make them available to tests and benchmarks
|
||||
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
MUJOCO_MODELS
|
||||
CONFIGURE_DEPENDS
|
||||
"*.xml"
|
||||
"*.png"
|
||||
)
|
||||
file(COPY ${MUJOCO_MODELS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
+45
-26
@@ -31,44 +31,63 @@ need to be downloaded or installed separately.
|
||||
|
||||
### Source
|
||||
|
||||
**Note.** Building from source is only necessary if you are modifying the Python bindings (or are trying to run on exceptionally old Linux systems). If that's not the case, then we recommend installing the prebuilt binaries from PyPI.
|
||||
**IMPORTANT:** Building from source is only necessary if you are modifying the
|
||||
Python bindings (or are trying to run on exceptionally old Linux systems).
|
||||
If that's not the case, then we recommend installing the prebuilt binaries from
|
||||
PyPI.
|
||||
|
||||
Before proceeding, make sure you have CMake and a C++17 compiler installed.
|
||||
1. Make sure you have CMake and a C++17 compiler installed.
|
||||
|
||||
1. Download the latest release of the [binary archives](https://github.com/deepmind/mujoco/releases) from GitHub. On macOS, the download corresponds to a DMG file from which you can drag the `MuJoCo` app into your Applications folder.
|
||||
1. Download the [latest binary release](https://github.com/deepmind/mujoco/releases)
|
||||
from GitHub. On macOS, the download corresponds to a DMG file from which you
|
||||
can drag `MuJoCo.app` into your `/Applications` folder.
|
||||
|
||||
2. Clone the entire `mujoco` repository from GitHub and `cd` into the python directory.
|
||||
1. Clone the entire `mujoco` repository from GitHub and `cd` into the python
|
||||
directory.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/deepmind/mujoco.git
|
||||
cd mujoco/python
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/deepmind/mujoco.git
|
||||
cd mujoco/python
|
||||
```
|
||||
|
||||
3. Create a virtual environment:
|
||||
1. Create a virtual environment:
|
||||
|
||||
```bash
|
||||
python3 -m venv /tmp/mujoco
|
||||
source /tmp/mujoco/bin/activate
|
||||
```
|
||||
```bash
|
||||
python3 -m venv /tmp/mujoco
|
||||
source /tmp/mujoco/bin/activate
|
||||
```
|
||||
|
||||
4. Generate a [source distribution](https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist)
|
||||
tarball with the `make_sdist.sh` script.
|
||||
1. Generate a [source distribution](https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist)
|
||||
tarball with the `make_sdist.sh` script.
|
||||
|
||||
```bash
|
||||
cd python
|
||||
bash make_sdist.sh
|
||||
```
|
||||
```bash
|
||||
cd python
|
||||
bash make_sdist.sh
|
||||
```
|
||||
|
||||
The `make_sdist.sh` script generates additional C++ header files that are needed to build the bindings, and also pulls in required files from elsewhere in the repository outside the `python` directory into the sdist. Upon completion, the script will create a `dist` directory with a `mujoco-2.1.X.tar.gz` file (where X is the version number of the release).
|
||||
The `make_sdist.sh` script generates additional C++ header files that are
|
||||
needed to build the bindings, and also pulls in required files from elsewhere
|
||||
in the repository outside the `python` directory into the sdist. Upon
|
||||
completion, the script will create a `dist` directory with a
|
||||
`mujoco-x.y.z.tar.gz` file (where `x.y.z` is the version number).
|
||||
|
||||
5. Install the generated tarball. You'll need to specify the path to the MuJoCo library you downloaded earlier. For example, on macOS, this will be `/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.framework` if you dragged it to your Applications folder.
|
||||
1. Use the generated source distribution to build and install the bindings.
|
||||
You'll need to specify the path to the MuJoCo library you downloaded earlier
|
||||
in the `MUJOCO_PATH` environment variable.
|
||||
|
||||
```bash
|
||||
cd dist
|
||||
MUJOCO_PATH=/PATH/TO/MUJOCO pip install mujoco-2.1.X.tar.gz
|
||||
```
|
||||
**Note**: For macOS, this can be the path to a directory that contains the
|
||||
`mujoco.framework`. In particular, you can set
|
||||
`MUJOCO_PATH=/Applications/MuJoCo.app` if you installed MuJoCo as suggested
|
||||
in step 1.
|
||||
|
||||
The Python bindings should now be installed! To check that they've been successfully installed, `cd` outside of the `mujoco` directory and run `python -c "import mujoco"`.
|
||||
```bash
|
||||
cd dist
|
||||
MUJOCO_PATH=/PATH/TO/MUJOCO pip install mujoco-x.y.z.tar.gz
|
||||
```
|
||||
|
||||
The Python bindings should now be installed! To check that they've been
|
||||
successfully installed, `cd` outside of the `mujoco` directory and run
|
||||
`python -c "import mujoco"`.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -40,32 +40,60 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
separate_arguments(CMDLINE_LINK_OPTIONS UNIX_COMMAND ${CMAKE_SHARED_LINKER_FLAGS})
|
||||
add_link_options(${CMDLINE_LINK_OPTIONS})
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/Gy /Gw /Oi)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-fdata-sections -ffunction-sections)
|
||||
endif()
|
||||
|
||||
include(MujocoLinkOptions)
|
||||
get_mujoco_extra_link_options(EXTRA_LINK_OPTIONS)
|
||||
add_link_options(${EXTRA_LINK_OPTIONS})
|
||||
|
||||
if(APPLE)
|
||||
add_compile_options(-Werror=partial-availability -Werror=unguarded-availability)
|
||||
add_link_options(-Wl,-no_weak_imports)
|
||||
include(MujocoMacOS)
|
||||
enforce_mujoco_macosx_min_version()
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include(MujocoHarden)
|
||||
add_compile_options("${MUJOCO_HARDEN_COMPILE_OPTIONS}")
|
||||
add_link_options("${MUJOCO_HARDEN_LINK_OPTIONS}")
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter Development)
|
||||
|
||||
include(FindOrFetch)
|
||||
|
||||
# ==================== MUJOCO LIBRARY ==========================================
|
||||
if(NOT TARGET mujoco)
|
||||
find_library(MUJOCO_LIBRARY mujoco mujoco.2.1.5 HINTS ${MUJOCO_LIBRARY_DIR} REQUIRED)
|
||||
find_path(MUJOCO_INCLUDE mujoco.h HINTS ${MUJOCO_INCLUDE_DIR} REQUIRED)
|
||||
message("MuJoCo is at ${MUJOCO_LIBRARY}")
|
||||
message("MuJoCo headers are at ${MUJOCO_INCLUDE}")
|
||||
add_library(mujoco SHARED IMPORTED)
|
||||
if(APPLE)
|
||||
# On macOS, check if we are using mujoco.framework first.
|
||||
# Framework headers are searched differently from normal headers.
|
||||
# We need to use -F instead of the usual target_include_directories.
|
||||
find_path(MUJOCO_FRAMEWORK mujoco.Framework HINTS ${MUJOCO_FRAMEWORK_DIR})
|
||||
if(MUJOCO_FRAMEWORK)
|
||||
message("MuJoCo framework is at ${MUJOCO_FRAMEWORK}/mujoco.framework")
|
||||
set(MUJOCO_LIBRARY ${MUJOCO_FRAMEWORK}/mujoco.framework/Versions/A/libmujoco.2.2.0.dylib)
|
||||
target_compile_options(mujoco INTERFACE -F${MUJOCO_FRAMEWORK})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MUJOCO_FRAMEWORK)
|
||||
find_library(MUJOCO_LIBRARY mujoco mujoco.2.2.0 HINTS ${MUJOCO_LIBRARY_DIR} REQUIRED)
|
||||
find_path(MUJOCO_INCLUDE mujoco/mujoco.h HINTS ${MUJOCO_INCLUDE_DIR} REQUIRED)
|
||||
message("MuJoCo is at ${MUJOCO_LIBRARY}")
|
||||
message("MuJoCo headers are at ${MUJOCO_INCLUDE}")
|
||||
target_include_directories(mujoco INTERFACE "${MUJOCO_INCLUDE}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(mujoco PROPERTIES IMPORTED_IMPLIB "${MUJOCO_LIBRARY}")
|
||||
else()
|
||||
set_target_properties(mujoco PROPERTIES IMPORTED_LOCATION "${MUJOCO_LIBRARY}")
|
||||
endif()
|
||||
target_include_directories(mujoco INTERFACE "${MUJOCO_INCLUDE}")
|
||||
|
||||
if(APPLE)
|
||||
execute_process(
|
||||
COMMAND otool -XD ${MUJOCO_LIBRARY}
|
||||
@@ -88,18 +116,7 @@ if(NOT TARGET mujoco)
|
||||
endif()
|
||||
|
||||
# ==================== ABSEIL ==================================================
|
||||
if(APPLE)
|
||||
set(ABSL_EXTRA_FETCH_ARGS
|
||||
PATCH_COMMAND
|
||||
"sed"
|
||||
"-i"
|
||||
" "
|
||||
"s/-march=armv8-a+crypto/-mcpu=apple-m1+crypto/g"
|
||||
"${CMAKE_BINARY_DIR}/_deps/abseil-cpp-src/absl/copts/GENERATED_AbseilCopts.cmake"
|
||||
)
|
||||
else()
|
||||
set(ABSL_EXTRA_FETCH_ARGS "")
|
||||
endif()
|
||||
set(MUJOCO_PYTHON_ABSL_TARGETS absl::core_headers absl::flat_hash_map absl::span)
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
@@ -110,14 +127,26 @@ findorfetch(
|
||||
GIT_REPO
|
||||
https://github.com/abseil/abseil-cpp
|
||||
GIT_TAG
|
||||
215105818dfde3174fe799600bb0f3cae233d0bf # 20211102.0
|
||||
78f9680225b9792c26dfdd99d0bd26c96de53dd4 # # Fixes universal builds for macOS
|
||||
TARGETS
|
||||
absl::core_headers
|
||||
absl::flat_hash_map
|
||||
absl::span
|
||||
${ABSL_EXTRA_FETCH_ARGS}
|
||||
${MUJOCO_PYTHON_ABSL_TARGETS}
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
foreach(absl_target IN ITEMS ${MUJOCO_PYTHON_ABSL_TARGETS})
|
||||
get_target_property(absl_target_aliased ${absl_target} ALIASED_TARGET)
|
||||
if(absl_target_aliased)
|
||||
set(absl_target ${absl_target_aliased})
|
||||
endif()
|
||||
get_target_property(absl_target_type ${absl_target} TYPE)
|
||||
if(NOT
|
||||
${absl_target_type}
|
||||
STREQUAL
|
||||
"INTERFACE_LIBRARY"
|
||||
)
|
||||
target_compile_options(${absl_target} PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(${absl_target} PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# ==================== EIGEN ===================================================
|
||||
add_compile_definitions(EIGEN_MPL2_ONLY)
|
||||
@@ -138,26 +167,21 @@ findorfetch(
|
||||
)
|
||||
|
||||
# ==================== PYBIND11 ================================================
|
||||
if(MUJOCO_PYBIND11_DIR)
|
||||
FetchContent_Declare(pybind11 SOURCE_DIR ${MUJOCO_PYBIND11_DIR} EXCLUDE_FROM_ALL)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
else()
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
pybind11
|
||||
LIBRARY_NAME
|
||||
pybind11
|
||||
GIT_REPO
|
||||
https://github.com/pybind/pybind11
|
||||
GIT_TAG
|
||||
a8f1a5567608f346bdba293b3d062a288ee16cd4
|
||||
TARGETS
|
||||
pybind11::pybind11_headers
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
endif()
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
OFF
|
||||
PACKAGE_NAME
|
||||
pybind11
|
||||
LIBRARY_NAME
|
||||
pybind11
|
||||
GIT_REPO
|
||||
https://github.com/pybind/pybind11
|
||||
GIT_TAG
|
||||
a8f1a5567608f346bdba293b3d062a288ee16cd4
|
||||
TARGETS
|
||||
pybind11::pybind11_headers
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
# ==================== MUJOCO PYTHON BINDINGS ==================================
|
||||
|
||||
@@ -222,6 +246,7 @@ target_link_libraries(
|
||||
structs_header
|
||||
INTERFACE absl::flat_hash_map
|
||||
absl::span
|
||||
crossplatform
|
||||
mujoco
|
||||
raw
|
||||
)
|
||||
@@ -246,6 +271,19 @@ get_avx_compile_options(AVX_COMPILE_OPTIONS)
|
||||
macro(mujoco_pybind11_module name)
|
||||
pybind11_add_module(${name} ${ARGN})
|
||||
target_compile_options(${name} PRIVATE ${AVX_COMPILE_OPTIONS})
|
||||
if(NOT MSVC)
|
||||
target_compile_options(${name} PRIVATE -Wall -Werror)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL GNU)
|
||||
target_compile_options(
|
||||
${name}
|
||||
PRIVATE -Wno-int-in-bool-context
|
||||
-Wno-maybe-uninitialized
|
||||
-Wno-sign-compare
|
||||
-Wno-stringop-overflow
|
||||
-Wno-stringop-truncation
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(APPLE)
|
||||
add_custom_command(
|
||||
@@ -323,6 +361,7 @@ mujoco_pybind11_module(
|
||||
target_link_libraries(
|
||||
_structs
|
||||
PRIVATE absl::flat_hash_map
|
||||
crossplatform
|
||||
mujoco
|
||||
raw
|
||||
errors_header
|
||||
|
||||
@@ -53,6 +53,6 @@ if _MUJOCO_GL not in ('disable', 'disabled', 'off', 'false', '0'):
|
||||
else:
|
||||
from mujoco.glfw import GLContext
|
||||
|
||||
HEADERS_DIR = os.path.join(os.path.dirname(__file__), 'include')
|
||||
HEADERS_DIR = os.path.join(os.path.dirname(__file__), 'include/mujoco')
|
||||
|
||||
__version__ = mj_versionString() # pylint: disable=undefined-variable
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "errors.h"
|
||||
#include "structs.h"
|
||||
#include "raw.h"
|
||||
|
||||
@@ -71,7 +71,7 @@ struct {enum.name} {{
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
namespace mujoco::python_traits {{
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ struct {func.name} {{
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "util/crossplatform.h"
|
||||
|
||||
namespace mujoco::python_traits {{
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <mjmodel.h>
|
||||
#include <mjvisualize.h>
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include <pybind11/cast.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace mujoco::python {
|
||||
namespace {
|
||||
@@ -32,7 +32,7 @@ py::tuple MakeTuple(
|
||||
for (int i = 0; i < N; i++) {
|
||||
result.append(py::str(strings[i]));
|
||||
}
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
template <auto N>
|
||||
@@ -44,7 +44,7 @@ py::tuple MakeTuple(const char* (&strings)[N][3]) {
|
||||
py::str(strings[i][1]),
|
||||
py::str(strings[i][2])));
|
||||
}
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(_constants, pymodule) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include <mjexport.h>
|
||||
#include <mujoco/mjexport.h>
|
||||
#include "util/crossplatform.h"
|
||||
#include "util/func_wrap.h"
|
||||
#include <pybind11/pybind11.h>
|
||||
@@ -109,7 +109,7 @@ class ErrorBase : public pybind11::builtin_exception {
|
||||
static thread_local std::jmp_buf mju_error_jmp_buf;
|
||||
static thread_local std::array<char, 1024> mju_error_msg{0};
|
||||
|
||||
static void MjErrorHandler(const char* msg) {
|
||||
static inline void MjErrorHandler(const char* msg) {
|
||||
std::strncpy(mju_error_msg.data(), msg, mju_error_msg.size());
|
||||
std::longjmp(mju_error_jmp_buf, 1);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "errors.h"
|
||||
#include "structs.h"
|
||||
#include "util/array_traits.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
||||
#define MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
||||
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
|
||||
#define MJMODEL_ACTUATOR \
|
||||
X( int, actuator_, trntype, nu, 1 ) \
|
||||
@@ -26,11 +26,13 @@
|
||||
X( int, actuator_, group, nu, 1 ) \
|
||||
X( mjtByte, actuator_, ctrllimited, nu, 1 ) \
|
||||
X( mjtByte, actuator_, forcelimited, nu, 1 ) \
|
||||
X( mjtByte, actuator_, actlimited, nu, 1 ) \
|
||||
X( mjtNum, actuator_, dynprm, nu, mjNDYN ) \
|
||||
X( mjtNum, actuator_, gainprm, nu, mjNGAIN ) \
|
||||
X( mjtNum, actuator_, biasprm, nu, mjNBIAS ) \
|
||||
X( mjtNum, actuator_, ctrlrange, nu, 2 ) \
|
||||
X( mjtNum, actuator_, forcerange, nu, 2 ) \
|
||||
X( mjtNum, actuator_, actrange, nu, 2 ) \
|
||||
X( mjtNum, actuator_, gear, nu, 6 ) \
|
||||
X( mjtNum, actuator_, cranklength, nu, 1 ) \
|
||||
X( mjtNum, actuator_, acc0, nu, 1 ) \
|
||||
@@ -361,8 +363,8 @@
|
||||
X( mjtNum, , qfrc_bias, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_passive, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_actuator, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_unc, nv, 1 ) \
|
||||
X( mjtNum, , qacc_unc, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_smooth, nv, 1 ) \
|
||||
X( mjtNum, , qacc_smooth, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_constraint, nv, 1 ) \
|
||||
X( mjtNum, , qfrc_inverse, nv, 1 )
|
||||
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "errors.h"
|
||||
#include "indexers.h"
|
||||
#include "mjdata_meta.h"
|
||||
#include "raw.h"
|
||||
#include <pybind11/pybind11.h>
|
||||
#include "util/crossplatform.h"
|
||||
|
||||
namespace mujoco::python {
|
||||
|
||||
@@ -218,13 +217,15 @@ MJDATA_VIEW_GROUPS
|
||||
#undef XGROUP
|
||||
|
||||
#define MAKE_SHAPE(dim) \
|
||||
[n = (dim)]() -> std::vector<int> { \
|
||||
MUJOCO_DIAG_IGNORE_UNUSED_LAMBDA_CAPTURE \
|
||||
[n = (dim)]() -> std::vector<int> { \
|
||||
if constexpr (std::string_view(#dim) == std::string_view("1")) { \
|
||||
return {}; \
|
||||
} else { \
|
||||
return {n}; \
|
||||
} \
|
||||
}()
|
||||
}() \
|
||||
MUJOCO_DIAG_UNIGNORE_UNUSED_LAMBDA_CAPTURE
|
||||
|
||||
#undef MJ_M
|
||||
#define MJ_M(n) m_->n
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <absl/container/flat_hash_map.h>
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include "indexer_xmacro.h"
|
||||
#include "mjdata_meta.h"
|
||||
#include "raw.h"
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#ifndef MUJOCO_PYTHON_MJDATA_META_H_
|
||||
#define MUJOCO_PYTHON_MJDATA_META_H_
|
||||
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include "raw.h"
|
||||
#include "util/crossplatform.h"
|
||||
|
||||
namespace mujoco::python {
|
||||
namespace _impl {
|
||||
@@ -95,7 +96,8 @@ struct MjDataMetadata {
|
||||
#undef X
|
||||
dummy_() {}
|
||||
|
||||
bool dummy_; // Dummy variable to terminate X macro sequences.
|
||||
// Dummy variable to terminate X macro sequences.
|
||||
MUJOCO_MAYBE_UNUSED bool dummy_;
|
||||
};
|
||||
|
||||
} // namespace mujoco::python
|
||||
|
||||
+4
-4
@@ -15,10 +15,10 @@
|
||||
#ifndef MUJOCO_PYTHON_RAW_H_
|
||||
#define MUJOCO_PYTHON_RAW_H_
|
||||
|
||||
#include <mjdata.h>
|
||||
#include <mjmodel.h>
|
||||
#include <mjrender.h>
|
||||
#include <mjvisualize.h>
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjrender.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
|
||||
// Type aliases for MuJoCo C structs to allow us refer to consistently refer
|
||||
// to them under the "raw" namespace.
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <mjrender.h>
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mjrender.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "errors.h"
|
||||
#include "function_traits.h"
|
||||
#include "functions.h"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <mjtnum.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
|
||||
namespace mujoco::python::_impl {
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include <absl/container/flat_hash_map.h>
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "errors.h"
|
||||
#include "function_traits.h"
|
||||
#include "indexers.h"
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include <absl/types/span.h>
|
||||
#include <mujoco.h>
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include "indexers.h"
|
||||
#include "mjdata_meta.h"
|
||||
#include "raw.h"
|
||||
@@ -894,7 +894,7 @@ static InitPyArray(Shape&& shape, T* buf, pybind11::handle owner) {
|
||||
out.append(InitPyArray(block_shape, &buf[i * block_size], owner));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
return std::move(out);
|
||||
}
|
||||
|
||||
// Same as above, but where we can determine array dimensions through the
|
||||
|
||||
@@ -23,11 +23,6 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
# INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
|
||||
if(APPLE)
|
||||
add_compile_options(-Werror=partial-availability -Werror=unguarded-availability)
|
||||
add_link_options(-Wl,-no_weak_imports)
|
||||
endif()
|
||||
|
||||
add_library(crossplatform INTERFACE)
|
||||
target_sources(crossplatform INTERFACE crossplatform.h)
|
||||
set_target_properties(crossplatform PROPERTIES PUBLIC_HEADER crossplatform.h)
|
||||
@@ -62,7 +57,8 @@ target_link_libraries(
|
||||
func_traits
|
||||
)
|
||||
|
||||
if(MUJOCO_TEST_PYTHON_UTIL)
|
||||
if(BUILD_TESTING)
|
||||
enable_testing()
|
||||
add_executable(array_traits_test array_traits_test.cc)
|
||||
target_link_libraries(
|
||||
array_traits_test
|
||||
|
||||
@@ -48,4 +48,29 @@
|
||||
#define MUJOCO_ALWAYS_INLINE_LAMBDA_MUTABLE
|
||||
#endif
|
||||
|
||||
#ifndef MUJOCO_DIAG_IGNORE_UNUSED_LAMBDA_CAPTURE
|
||||
#if defined(__clang__)
|
||||
#define MUJOCO_DIAG_IGNORE_UNUSED_LAMBDA_CAPTURE \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wunused-lambda-capture\"")
|
||||
#define MUJOCO_DIAG_UNIGNORE_UNUSED_LAMBDA_CAPTURE \
|
||||
_Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__)
|
||||
#define MUJOCO_DIAG_IGNORE_UNUSED_LAMBDA_CAPTURE \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wunused-lambda-capture\"")
|
||||
#define MUJOCO_DIAG_UNIGNORE_UNUSED_LAMBDA_CAPTURE _Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define MUJOCO_DIAG_IGNORE_UNUSED_LAMBDA_CAPTURE
|
||||
#define MUJOCO_DIAG_UNIGNORE_UNUSED_LAMBDA_CAPTURE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// GCC ignores [[maybe_unused]] and emits a -Wattributes
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#define MUJOCO_MAYBE_UNUSED
|
||||
#else
|
||||
#define MUJOCO_MAYBE_UNUSED [[maybe_unused]]
|
||||
#endif
|
||||
|
||||
#endif // MUJOCO_PYTHON_UTIL_CROSSPLATFORM_H_
|
||||
|
||||
+34
-18
@@ -30,7 +30,7 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command import build_ext
|
||||
|
||||
__version__ = '2.1.5'
|
||||
__version__ = '2.2.0'
|
||||
|
||||
MUJOCO_CMAKE = 'MUJOCO_CMAKE'
|
||||
MUJOCO_CMAKE_ARGS = 'MUJOCO_CMAKE_ARGS'
|
||||
@@ -137,7 +137,10 @@ class BuildCMakeExtension(build_ext.build_ext):
|
||||
"""Uses CMake to build extensions."""
|
||||
|
||||
def run(self):
|
||||
self._mujoco_library_path, self._mujoco_include_path = self._find_mujoco()
|
||||
self._is_apple = (platform.system() == 'Darwin')
|
||||
(self._mujoco_library_path,
|
||||
self._mujoco_include_path,
|
||||
self._mujoco_framework_path) = self._find_mujoco()
|
||||
self._configure_cmake()
|
||||
for ext in self.extensions:
|
||||
assert ext.name.startswith(EXT_PREFIX)
|
||||
@@ -151,13 +154,17 @@ class BuildCMakeExtension(build_ext.build_ext):
|
||||
raise RuntimeError(f'{MUJOCO_PATH} environment variable is not set')
|
||||
library_path = None
|
||||
include_path = None
|
||||
for directory, _, filenames in os.walk(os.environ['MUJOCO_PATH']):
|
||||
for directory, subdirs, filenames in os.walk(os.environ['MUJOCO_PATH']):
|
||||
if self._is_apple and 'mujoco.framework' in subdirs:
|
||||
return (os.path.join(directory, 'mujoco.framework/Versions/A'),
|
||||
os.path.join(directory, 'mujoco.framework/Headers'),
|
||||
directory)
|
||||
if fnmatch.filter(filenames, get_mujoco_lib_pattern()):
|
||||
library_path = directory
|
||||
if fnmatch.filter(filenames, 'mujoco.h'):
|
||||
if os.path.exists(os.path.join(directory, 'mujoco/mujoco.h')):
|
||||
include_path = directory
|
||||
if library_path and include_path:
|
||||
return library_path, include_path
|
||||
return library_path, include_path, None
|
||||
raise RuntimeError('Cannot find MuJoCo library and/or include paths')
|
||||
|
||||
def _copy_external_libraries(self):
|
||||
@@ -171,8 +178,8 @@ class BuildCMakeExtension(build_ext.build_ext):
|
||||
def _copy_mujoco_headers(self):
|
||||
dst = os.path.join(
|
||||
os.path.dirname(self.get_ext_fullpath(self.extensions[0].name)),
|
||||
'include')
|
||||
os.mkdir(dst)
|
||||
'include/mujoco')
|
||||
os.makedirs(dst)
|
||||
for directory, _, filenames in os.walk(self._mujoco_include_path):
|
||||
for filename in fnmatch.filter(filenames, '*.h'):
|
||||
shutil.copyfile(os.path.join(directory, filename),
|
||||
@@ -184,18 +191,27 @@ class BuildCMakeExtension(build_ext.build_ext):
|
||||
build_cfg = 'Debug' if self.debug else 'Release'
|
||||
cmake_module_path = os.path.join(os.path.dirname(__file__), 'cmake')
|
||||
cmake_args = [
|
||||
f'-DPython3_ROOT_DIR={sys.prefix}',
|
||||
f'-DPython3_EXECUTABLE={sys.executable}',
|
||||
f'-DMUJOCO_LIBRARY_DIR={self._mujoco_library_path}',
|
||||
f'-DMUJOCO_INCLUDE_DIR={self._mujoco_include_path}',
|
||||
f'-DCMAKE_MODULE_PATH={cmake_module_path}',
|
||||
f'-DCMAKE_BUILD_TYPE={build_cfg}',
|
||||
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={self.build_temp}',
|
||||
f'-DCMAKE_INTERPROCEDURAL_OPTIMIZATION={"OFF" if self.debug else "ON"}',
|
||||
f'-DPython3_ROOT_DIR:PATH={sys.prefix}',
|
||||
f'-DPython3_EXECUTABLE:STRING={sys.executable}',
|
||||
f'-DCMAKE_MODULE_PATH:PATH={cmake_module_path}',
|
||||
f'-DCMAKE_BUILD_TYPE:STRING={build_cfg}',
|
||||
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH={self.build_temp}',
|
||||
f'-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=:BOOL{"OFF" if self.debug else "ON"}',
|
||||
'-DCMAKE_Fortran_COMPILER:STRING=',
|
||||
'-DCMAKE_VERBOSE_MAKEFILE=ON',
|
||||
'-DBUILD_TESTING=OFF',
|
||||
'-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON',
|
||||
'-DBUILD_TESTING:BOOL=OFF',
|
||||
]
|
||||
|
||||
if self._mujoco_framework_path is not None:
|
||||
cmake_args.extend([
|
||||
f'-DMUJOCO_FRAMEWORK_DIR:PATH={self._mujoco_framework_path}',
|
||||
])
|
||||
else:
|
||||
cmake_args.extend([
|
||||
f'-DMUJOCO_LIBRARY_DIR:PATH={self._mujoco_library_path}',
|
||||
f'-DMUJOCO_INCLUDE_DIR:PATH={self._mujoco_include_path}',
|
||||
])
|
||||
|
||||
if platform.system() != 'Windows':
|
||||
cmake_args.extend([
|
||||
f'-DPython3_LIBRARY={sysconfig.get_paths()["stdlib"]}',
|
||||
@@ -293,7 +309,7 @@ setup(
|
||||
'libmujoco.*.dylib',
|
||||
'libmujoco*.so.*',
|
||||
'mujoco.dll',
|
||||
'include/*.h',
|
||||
'include/mujoco/*.h',
|
||||
]),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
# Default to GLVND if available.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0072 NEW)
|
||||
|
||||
# This line has to appear before 'PROJECT' in order to be able to disable incremental linking
|
||||
set(MSVC_INCREMENTAL_DEFAULT ON)
|
||||
|
||||
project(
|
||||
mujoco_samples
|
||||
VERSION 2.1.5
|
||||
DESCRIPTION "MuJoCo samples binaries"
|
||||
HOMEPAGE_URL "https://mujoco.org"
|
||||
)
|
||||
|
||||
enable_language(C)
|
||||
enable_language(CXX)
|
||||
if(APPLE)
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
endif()
|
||||
|
||||
# Check if we are building as standalone project.
|
||||
set(SAMPLE_STANDALONE OFF)
|
||||
set(_INSTALL_SAMPLES ON)
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(SAMPLE_STANDALONE ON)
|
||||
# If standalone, do not install the samples.
|
||||
set(_INSTALL_SAMPLES OFF)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
|
||||
if(SAMPLE_STANDALONE)
|
||||
include(SampleOptions)
|
||||
else()
|
||||
enforce_mujoco_macosx_min_version()
|
||||
endif()
|
||||
include(SampleDependencies)
|
||||
|
||||
set(MUJOCO_SAMPLE_COMPILE_OPTIONS "${AVX_COMPILE_OPTIONS}" "${EXTRA_COMPILE_OPTIONS}")
|
||||
set(MUJOCO_SAMPLE_LINK_OPTIONS "${EXTRA_LINK_OPTIONS}")
|
||||
|
||||
if(MUJOCO_HARDEN)
|
||||
if(WIN32)
|
||||
set(MUJOCO_SAMPLE_LINK_OPTIONS "${MUJOCO_SAMPLE_LINK_OPTIONS}" -Wl,/DYNAMICBASE)
|
||||
else()
|
||||
set(MUJOCO_SAMPLE_COMPILE_OPTIONS "${MUJOCO_SAMPLE_COMPILE_OPTIONS}" -fPIE)
|
||||
if(APPLE)
|
||||
set(MUJOCO_SAMPLE_LINK_OPTIONS "${MUJOCO_SAMPLE_LINK_OPTIONS}" -Wl,-pie)
|
||||
else()
|
||||
set(MUJOCO_SAMPLE_LINK_OPTIONS "${MUJOCO_SAMPLE_LINK_OPTIONS}" -pie)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Utility library
|
||||
add_library(uitools STATIC)
|
||||
target_sources(uitools PRIVATE uitools.h uitools.c)
|
||||
target_include_directories(uitools PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_options(uitools PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(uitools PUBLIC glfw mujoco::mujoco)
|
||||
target_link_options(uitools PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
# Build sample binaries
|
||||
add_executable(compile compile.cc)
|
||||
target_compile_options(compile PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(compile Threads::Threads)
|
||||
target_link_options(compile PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
add_executable(derivative derivative.cc)
|
||||
target_compile_options(derivative PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(derivative Threads::Threads)
|
||||
target_link_options(derivative PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
add_executable(testspeed testspeed.cc)
|
||||
target_compile_options(testspeed PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(testspeed Threads::Threads)
|
||||
target_link_options(testspeed PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
add_executable(testxml testxml.cc array_safety.h)
|
||||
target_compile_options(testxml PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(testxml Threads::Threads)
|
||||
target_link_options(testxml PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
target_link_libraries(compile mujoco::mujoco)
|
||||
target_link_libraries(derivative mujoco::mujoco)
|
||||
target_link_libraries(testspeed mujoco::mujoco)
|
||||
target_link_libraries(testxml mujoco::mujoco)
|
||||
|
||||
# Build samples that require GLFW.
|
||||
|
||||
add_executable(basic basic.cc)
|
||||
target_compile_options(basic PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(
|
||||
basic
|
||||
mujoco::mujoco
|
||||
glfw
|
||||
Threads::Threads
|
||||
)
|
||||
target_link_options(basic PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
add_executable(record record.cc array_safety.h)
|
||||
target_compile_options(record PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(
|
||||
record
|
||||
mujoco::mujoco
|
||||
glfw
|
||||
Threads::Threads
|
||||
)
|
||||
target_link_options(record PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
if(APPLE)
|
||||
set(SIMULATE_RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../dist/mujoco.icns)
|
||||
elseif(WIN32)
|
||||
set(SIMULATE_RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../dist/appicon.rc)
|
||||
else()
|
||||
set(SIMULATE_RESOURCE_FILES "")
|
||||
endif()
|
||||
|
||||
add_executable(simulate simulate.cc array_safety.h ${SIMULATE_RESOURCE_FILES})
|
||||
target_compile_options(simulate PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
if(WIN32)
|
||||
add_custom_command(
|
||||
TARGET simulate
|
||||
PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../dist/mujoco.ico
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E rm ${CMAKE_CURRENT_SOURCE_DIR}/mujoco.ico
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
simulate
|
||||
mujoco::mujoco
|
||||
uitools
|
||||
glfw
|
||||
Threads::Threads
|
||||
)
|
||||
target_link_options(simulate PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
if(APPLE)
|
||||
target_sources(simulate PRIVATE macos_save.mm)
|
||||
target_link_libraries(simulate "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
if(NOT SAMPLE_STANDALONE)
|
||||
if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
|
||||
|
||||
macro(link_to_mujoco_framework target)
|
||||
get_target_property(interface_link_libraries ${target} INTERFACE_LINK_LIBRARIES)
|
||||
get_target_property(link_libraries ${target} LINK_LIBRARIES)
|
||||
# Remove mujoco::mujoco target which is the not-framework library.
|
||||
list(REMOVE_ITEM interface_link_libraries mujoco::mujoco)
|
||||
list(REMOVE_ITEM link_libraries mujoco::mujoco)
|
||||
set_target_properties(
|
||||
${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${interface_link_libraries}"
|
||||
)
|
||||
set_target_properties(${target} PROPERTIES LINK_LIBRARIES "${link_libraries}")
|
||||
|
||||
# Add mujoco_framework.
|
||||
target_link_libraries(${target} mujoco_framework)
|
||||
endmacro()
|
||||
|
||||
include(DuplicateTarget)
|
||||
duplicate_target(
|
||||
TARGET
|
||||
simulate
|
||||
NEW_TARGET_NAME
|
||||
simulate_macos
|
||||
)
|
||||
link_to_mujoco_framework(simulate_macos)
|
||||
|
||||
set_target_properties(
|
||||
simulate_macos
|
||||
PROPERTIES INSTALL_RPATH @executable_path/../Frameworks
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
RESOURCE ${SIMULATE_RESOURCE_FILES}
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../dist/Info.plist.simulate.in
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "MuJoCo"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.mujoco.mujoco"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_INFO_STRING ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_ICON_FILE "mujoco.icns"
|
||||
MACOSX_BUNDLE_COPYRIGHT "Copyright 2021 DeepMind Technologies Limited."
|
||||
OUTPUT_NAME "simulate"
|
||||
)
|
||||
|
||||
macro(embed_in_bundle target)
|
||||
add_dependencies(${target} simulate_macos)
|
||||
set_target_properties(
|
||||
${target}
|
||||
PROPERTIES INSTALL_RPATH @executable_path/../Frameworks
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:simulate_macos>
|
||||
)
|
||||
endmacro()
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
basic
|
||||
NEW_TARGET_NAME
|
||||
basic_macos
|
||||
)
|
||||
set_target_properties(basic_macos PROPERTIES OUTPUT_NAME basic)
|
||||
link_to_mujoco_framework(basic_macos)
|
||||
embed_in_bundle(basic_macos simulate_macos)
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
compile
|
||||
NEW_TARGET_NAME
|
||||
compile_macos
|
||||
)
|
||||
set_target_properties(compile_macos PROPERTIES OUTPUT_NAME compile)
|
||||
link_to_mujoco_framework(compile_macos)
|
||||
embed_in_bundle(compile_macos simulate_macos)
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
derivative
|
||||
NEW_TARGET_NAME
|
||||
derivative_macos
|
||||
)
|
||||
set_target_properties(derivative_macos PROPERTIES OUTPUT_NAME derivative)
|
||||
link_to_mujoco_framework(derivative_macos)
|
||||
embed_in_bundle(derivative_macos simulate_macos)
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
record
|
||||
NEW_TARGET_NAME
|
||||
record_macos
|
||||
)
|
||||
set_target_properties(record_macos PROPERTIES OUTPUT_NAME record)
|
||||
link_to_mujoco_framework(record_macos)
|
||||
embed_in_bundle(record_macos simulate_macos)
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
testspeed
|
||||
NEW_TARGET_NAME
|
||||
testspeed_macos
|
||||
)
|
||||
set_target_properties(testspeed_macos PROPERTIES OUTPUT_NAME testspeed)
|
||||
link_to_mujoco_framework(testspeed_macos)
|
||||
embed_in_bundle(testspeed_macos simulate_macos)
|
||||
|
||||
duplicate_target(
|
||||
TARGET
|
||||
testxml
|
||||
NEW_TARGET_NAME
|
||||
testxml_macos
|
||||
)
|
||||
set_target_properties(testxml_macos PROPERTIES OUTPUT_NAME testxml)
|
||||
link_to_mujoco_framework(testxml_macos)
|
||||
embed_in_bundle(testxml_macos simulate_macos)
|
||||
|
||||
# Do not add the original binaries to the ALL target. We do this to speed up the
|
||||
# build assuming the user is interested in the Frameworks.
|
||||
set_target_properties(simulate PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
set_target_properties(basic PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
set_target_properties(derivative PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
set_target_properties(record PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
set_target_properties(testxml PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
# Note: compile and testspeed are needed by the tests.
|
||||
|
||||
# Embed mujoco.framework inside the App bundle ane move the icon file over too.
|
||||
add_custom_command(
|
||||
TARGET simulate_macos
|
||||
POST_BUILD
|
||||
COMMAND mkdir -p $<TARGET_FILE_DIR:simulate_macos>/../Frameworks
|
||||
COMMAND rm -rf $<TARGET_FILE_DIR:simulate_macos>/../Frameworks/mujoco.framework
|
||||
COMMAND cp -a $<TARGET_FILE_DIR:mujoco_framework>/../../../mujoco.framework
|
||||
$<TARGET_FILE_DIR:simulate_macos>/../Frameworks/
|
||||
# Delete the symlink and the TBD, otherwise we can't sign and notarize.
|
||||
COMMAND rm -rf $<TARGET_FILE_DIR:simulate_macos>/../Frameworks/mujoco.framework/mujoco.tbd
|
||||
COMMAND
|
||||
rm -rf
|
||||
$<TARGET_FILE_DIR:simulate_macos>/../Frameworks/mujoco.framework/Versions/A/libmujoco.dylib
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Do not install if macOS Bundles are created as RPATH is managed manually there.
|
||||
if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
|
||||
set(_INSTALL_SAMPLES OFF)
|
||||
endif()
|
||||
|
||||
if(_INSTALL_SAMPLES)
|
||||
|
||||
include(TargetAddRpath)
|
||||
|
||||
# Add support to RPATH for the samples.
|
||||
target_add_rpath(
|
||||
TARGETS
|
||||
basic
|
||||
compile
|
||||
derivative
|
||||
record
|
||||
testspeed
|
||||
testxml
|
||||
simulate
|
||||
INSTALL_DIRECTORY
|
||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
|
||||
LIB_DIRS
|
||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
|
||||
DEPENDS
|
||||
MUJOCO_ENABLE_RPATH
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS basic
|
||||
compile
|
||||
derivative
|
||||
record
|
||||
testspeed
|
||||
testxml
|
||||
simulate
|
||||
EXPORT ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples
|
||||
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT samples
|
||||
)
|
||||
|
||||
if(NOT MUJOCO_SAMPLES_USE_SYSTEM_GLFW)
|
||||
# We downloaded GLFW. Depending if it is a static or shared LIBRARY we might
|
||||
# need to install it.
|
||||
get_target_property(MJ_GLFW_LIBRARY_TYPE glfw TYPE)
|
||||
if(MJ_GLFW_LIBRARY_TYPE STREQUAL SHARED_LIBRARY)
|
||||
install(
|
||||
TARGETS glfw
|
||||
EXPORT ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT samples
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
# which is commonly available through your distro's package manager.
|
||||
# On Debian and Ubuntu, GLFW can be installed via `apt install libglfw3-dev`.
|
||||
|
||||
COMMON=-O2 -I../include -L../lib -std=c++11 -pthread -Wl,-no-as-needed -Wl,-rpath,'$$ORIGIN'/../lib
|
||||
COMMON=-O2 -I../include -L../lib -std=c++17 -pthread -Wl,-no-as-needed -Wl,-rpath,'$$ORIGIN'/../lib
|
||||
|
||||
all:
|
||||
$(CXX) $(COMMON) testxml.cc -lmujoco -o ../bin/testxml
|
||||
|
||||
+16
-16
@@ -1,23 +1,23 @@
|
||||
# This Makefile assumes that GLFW is installed via Homebrew, and that Homebrew
|
||||
# packages are installed in /usr/local. If your setup is different, you will
|
||||
# need to adjust the HOMEBREW variable accordingly.
|
||||
# This Makefile assumes that GLFW is installed via Homebrew.
|
||||
# If your setup is different, you will need to set GLFWROOT manually.
|
||||
|
||||
# This Makefile also assumes that MuJoCo.app is present in /Applications.
|
||||
|
||||
HOMEBREW?=/usr/local
|
||||
GLFWROOT?=$(shell brew --prefix)
|
||||
MUJOCOPATH?=/Applications/MuJoCo.app/Contents/Frameworks
|
||||
|
||||
MUJOCO_LIBDIR=/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.Framework/Versions/A
|
||||
MUJOCO_INCLUDEDIR=/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.Framework/Versions/A/Headers
|
||||
CFLAGS=-O2 -I$(MUJOCO_INCLUDEDIR) -I$(HOMEBREW)/include -pthread
|
||||
ALLFLAGS=$(CFLAGS) -L$(MUJOCO_LIBDIR) -L$(HOMEBREW)/lib -std=c++11 -stdlib=libc++ -Wl,-rpath,/Applications/MuJoCo.app/Contents/Frameworks
|
||||
CFLAGS=-O2 -F$(MUJOCOPATH) -I$(GLFWROOT)/include -pthread
|
||||
CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++
|
||||
ALLFLAGS=$(CXXFLAGS) -L$(GLFWROOT)/lib -Wl,-rpath,$(MUJOCOPATH)
|
||||
|
||||
all:
|
||||
clang++ $(ALLFLAGS) testxml.cc -lmujoco.2.1.5 -o testxml
|
||||
clang++ $(ALLFLAGS) testspeed.cc -lmujoco.2.1.5 -o testspeed
|
||||
clang++ $(ALLFLAGS) compile.cc -lmujoco.2.1.5 -o compile
|
||||
clang++ $(ALLFLAGS) derivative.cc -lmujoco.2.1.5 -o derivative
|
||||
clang++ $(ALLFLAGS) basic.cc -lmujoco.2.1.5 -lglfw -o basic
|
||||
clang++ $(ALLFLAGS) record.cc -lmujoco.2.1.5 -lglfw -o record
|
||||
clang -c $(CFLAGS) uitools.c
|
||||
clang++ $(ALLFLAGS) uitools.o simulate.cc -lmujoco.2.1.5 -lglfw -o simulate
|
||||
clang++ $(ALLFLAGS) testxml.cc -framework mujoco -o testxml
|
||||
clang++ $(ALLFLAGS) testspeed.cc -framework mujoco -o testspeed
|
||||
clang++ $(ALLFLAGS) compile.cc -framework mujoco -o compile
|
||||
clang++ $(ALLFLAGS) derivative.cc -framework mujoco -o derivative
|
||||
clang++ $(ALLFLAGS) basic.cc -framework mujoco -lglfw -o basic
|
||||
clang++ $(ALLFLAGS) record.cc -framework mujoco -lglfw -o record
|
||||
clang -c $(CFLAGS) uitools.c
|
||||
clang++ -c $(CXXFLAGS) macos_save.mm
|
||||
clang++ $(ALLFLAGS) simulate.cc uitools.o macos_save.o -framework mujoco -framework Cocoa -lglfw -o simulate
|
||||
rm *.o
|
||||
|
||||
+2
-2
@@ -15,8 +15,8 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include <mujoco.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
// MuJoCo data structures
|
||||
mjModel* m = NULL; // MuJoCo model
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# Assigns compiler options to the given variable based on availability of AVX.
|
||||
function(get_avx_compile_options OUTPUT_VAR)
|
||||
message(VERBOSE "Checking if AVX is available...")
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_REQUIRED_FLAGS "/arch:AVX")
|
||||
else()
|
||||
set(CMAKE_REQUIRED_FLAGS "-mavx")
|
||||
endif()
|
||||
|
||||
if(APPLE AND "x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES)
|
||||
message(STATUS "Building x86_64 on macOS, forcing CAN_BUILD_AVX to TRUE.")
|
||||
set(CAN_BUILD_AVX TRUE)
|
||||
else()
|
||||
check_c_source_compiles(
|
||||
"
|
||||
#include <immintrin.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
__m256d ymm;
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
CAN_BUILD_AVX
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CAN_BUILD_AVX)
|
||||
message(VERBOSE "Checking if AVX is available... AVX available.")
|
||||
set("${OUTPUT_VAR}"
|
||||
${CMAKE_REQUIRED_FLAGS}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
else()
|
||||
message(VERBOSE "Checking if AVX is available... AVX not available.")
|
||||
set("${OUTPUT_VAR}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,139 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#.rst:
|
||||
# FindOrFetch
|
||||
# ----------------------
|
||||
#
|
||||
# Find or fetch a package in order to satisfy target dependencies.
|
||||
#
|
||||
# FindOrFetch([USE_SYSTEM_PACKAGE [ON/OFF]]
|
||||
# [PACKAGE_NAME [name]]
|
||||
# [LIBRARY_NAME [name]]
|
||||
# [GIT_REPO [repo]]
|
||||
# [GIT_TAG [tag]]
|
||||
# [PATCH_COMMAND [cmd] [args]]
|
||||
# [TARGETS [targets]]
|
||||
# [EXCLUDE_FROM_ALL])
|
||||
#
|
||||
# The command has the following parameters:
|
||||
#
|
||||
# Arguments:
|
||||
# - ``USE_SYSTEM_PACKAGE`` one-value argument on whether to search for the
|
||||
# package in the system (ON) or whether to fetch the library using
|
||||
# FetchContent from the specified Git repository (OFF). Note that
|
||||
# FetchContent variables will override this behaviour.
|
||||
# - ``PACKAGE_NAME`` name of the system-package. Ignored if
|
||||
# ``USE_SYSTEM_PACKAGE`` is ``OFF``.
|
||||
# - ``LIBRARY_NAME`` name of the library. Ignored if
|
||||
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||
# - ``GIT_REPO`` git repository to fetch the library from. Ignored if
|
||||
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||
# - ``GIT_TAG`` tag reference when fetching the library from the git
|
||||
# repository. Ignored if ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||
# - ``PATCH_COMMAND`` Specifies a custom command to patch the sources after an
|
||||
# update. See https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add
|
||||
# for details on the parameter.
|
||||
# - ``TARGETS`` list of targets to be satisfied. If any of these targets are
|
||||
# not currently defined, this macro will attempt to either find or fetch the
|
||||
# package.
|
||||
# - ``EXCLUDE_FROM_ALL`` if specified, the targets are not added to the ``all``
|
||||
# metatarget.
|
||||
#
|
||||
# Note: if ``USE_SYSTEM_PACKAGE`` is ``OFF``, FetchContent will be used to
|
||||
# retrieve the specified targets. It is possible to specify any variable in
|
||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variables to
|
||||
# override this macro behaviour.
|
||||
|
||||
if(COMMAND FindOrFetch)
|
||||
return()
|
||||
endif()
|
||||
|
||||
macro(FindOrFetch)
|
||||
if(NOT FetchContent)
|
||||
include(FetchContent)
|
||||
endif()
|
||||
|
||||
# Parse arguments.
|
||||
set(options EXCLUDE_FROM_ALL)
|
||||
set(one_value_args
|
||||
USE_SYSTEM_PACKAGE
|
||||
PACKAGE_NAME
|
||||
LIBRARY_NAME
|
||||
GIT_REPO
|
||||
GIT_TAG
|
||||
)
|
||||
set(multi_value_args PATCH_COMMAND TARGETS)
|
||||
cmake_parse_arguments(
|
||||
_ARGS
|
||||
"${options}"
|
||||
"${one_value_args}"
|
||||
"${multi_value_args}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
# Check if all targets are found.
|
||||
if(NOT _ARGS_TARGETS)
|
||||
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
|
||||
endif()
|
||||
|
||||
set(targets_found TRUE)
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: checking for targets in package `${_ARGS_PACKAGE_NAME}`"
|
||||
)
|
||||
foreach(target ${_ARGS_TARGETS})
|
||||
if(NOT TARGET ${target})
|
||||
message(CHECK_FAIL "target `${target}` not defined.")
|
||||
set(targets_found FALSE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# If targets are not found, use `find_package` or `FetchContent...` to get it.
|
||||
if(NOT targets_found)
|
||||
if(${_ARGS_USE_SYSTEM_PACKAGE})
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: finding `${_ARGS_PACKAGE_NAME}` in system packages..."
|
||||
)
|
||||
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
|
||||
message(CHECK_PASS "found")
|
||||
else()
|
||||
message(CHECK_START
|
||||
"mujoco::FindOrFetch: Using FetchContent to retrieve `${_ARGS_LIBRARY_NAME}`"
|
||||
)
|
||||
FetchContent_Declare(
|
||||
${_ARGS_LIBRARY_NAME}
|
||||
GIT_REPOSITORY ${_ARGS_GIT_REPO}
|
||||
GIT_TAG ${_ARGS_GIT_TAG}
|
||||
GIT_SHALLOW FALSE
|
||||
PATCH_COMMAND ${_ARGS_PATCH_COMMAND}
|
||||
)
|
||||
if(${_ARGS_EXCLUDE_FROM_ALL})
|
||||
FetchContent_GetProperties(${_ARGS_LIBRARY_NAME})
|
||||
if(NOT ${${_ARGS_LIBRARY_NAME}_POPULATED})
|
||||
FetchContent_Populate(${_ARGS_LIBRARY_NAME})
|
||||
add_subdirectory(
|
||||
${${_ARGS_LIBRARY_NAME}_SOURCE_DIR} ${${_ARGS_LIBRARY_NAME}_BINARY_DIR}
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
|
||||
endif()
|
||||
message(CHECK_PASS "Done")
|
||||
endif()
|
||||
else()
|
||||
message(CHECK_PASS "found")
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
option(MUJOCO_HARDEN "Enable build hardening for MuJoCo." OFF)
|
||||
if(MUJOCO_HARDEN
|
||||
AND NOT
|
||||
CMAKE_CXX_COMPILER_ID
|
||||
MATCHES
|
||||
".*Clang.*"
|
||||
)
|
||||
message(FATAL_ERROR "MUJOCO_HARDEN is only supported when building with Clang")
|
||||
endif()
|
||||
|
||||
if(MUJOCO_HARDEN)
|
||||
set(MUJOCO_HARDEN_COMPILE_OPTIONS -D_FORTIFY_SOURCE=2 -fstack-protector)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS -Wl,-bind_at_load)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS -Wl,-z,relro -Wl,-z,now)
|
||||
endif()
|
||||
else()
|
||||
set(MUJOCO_HARDEN_COMPILE_OPTIONS "")
|
||||
set(MUJOCO_HARDEN_LINK_OPTIONS "")
|
||||
endif()
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# Gets the appropriate linker options for building MuJoCo, based on features available on the
|
||||
# linker.
|
||||
function(get_mujoco_extra_link_options OUTPUT_VAR)
|
||||
if(MSVC)
|
||||
set(EXTRA_LINK_OPTIONS /OPT:REF /OPT:ICF=5)
|
||||
else()
|
||||
set(EXTRA_LINK_OPTIONS)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_REQUIRED_FLAGS "-fuse-ld=lld-link")
|
||||
check_c_source_compiles("int main() {}" SUPPORTS_LLD)
|
||||
if(SUPPORTS_LLD)
|
||||
set(EXTRA_LINK_OPTIONS
|
||||
${EXTRA_LINK_OPTIONS}
|
||||
-fuse-ld=lld-link
|
||||
-Wl,/OPT:REF
|
||||
-Wl,/OPT:ICF
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_REQUIRED_FLAGS "-fuse-ld=lld")
|
||||
check_c_source_compiles("int main() {}" SUPPORTS_LLD)
|
||||
if(SUPPORTS_LLD)
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -fuse-ld=lld)
|
||||
else()
|
||||
set(CMAKE_REQUIRED_FLAGS "-fuse-ld=gold")
|
||||
check_c_source_compiles("int main() {}" SUPPORTS_GOLD)
|
||||
if(SUPPORTS_GOLD)
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -fuse-ld=gold)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS ${EXTRA_LINK_OPTIONS} "-Wl,--gc-sections")
|
||||
check_c_source_compiles("int main() {}" SUPPORTS_GC_SECTIONS)
|
||||
if(SUPPORTS_GC_SECTIONS)
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -Wl,--gc-sections)
|
||||
else()
|
||||
set(CMAKE_REQUIRED_FLAGS ${EXTRA_LINK_OPTIONS} "-Wl,-dead_strip")
|
||||
check_c_source_compiles("int main() {}" SUPPORTS_DEAD_STRIP)
|
||||
if(SUPPORTS_DEAD_STRIP)
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -Wl,-dead_strip)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set("${OUTPUT_VAR}"
|
||||
${EXTRA_LINK_OPTIONS}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endfunction()
|
||||
@@ -0,0 +1,38 @@
|
||||
# Copyright 2022 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if(APPLE)
|
||||
# 10.12 is the oldest version of macOS that supports C++17, launched 2016.
|
||||
set(MUJOCO_MACOSX_VERSION_MIN 10.12)
|
||||
|
||||
# We are setting the -mmacosx-version-min compiler flag directly rather than using the
|
||||
# CMAKE_OSX_DEPLOYMENT_TARGET variable since we do not want to affect choice of SDK,
|
||||
# and also we only want to apply the version restriction locally.
|
||||
set(MUJOCO_MACOS_COMPILE_OPTIONS -mmacosx-version-min=${MUJOCO_MACOSX_VERSION_MIN}
|
||||
-Werror=partial-availability -Werror=unguarded-availability
|
||||
)
|
||||
set(MUJOCO_MACOS_LINK_OPTIONS -mmacosx-version-min=${MUJOCO_MACOSX_VERSION_MIN}
|
||||
-Wl,-no_weak_imports
|
||||
)
|
||||
else()
|
||||
set(MUJOCO_MACOS_COMPILE_OPTIONS "")
|
||||
set(MUJOCO_MACOS_LINK_OPTIONS "")
|
||||
endif()
|
||||
|
||||
function(enforce_mujoco_macosx_min_version)
|
||||
if(APPLE)
|
||||
add_compile_options(${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
add_link_options(${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,102 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include(FindOrFetch)
|
||||
|
||||
if(SAMPLE_STANDALONE)
|
||||
# If standalone, by default look for MuJoCo binary version.
|
||||
set(DEFAULT_USE_SYSTEM_MUJOCO ON)
|
||||
else()
|
||||
set(DEFAULT_USE_SYSTEM_MUJOCO OFF)
|
||||
endif()
|
||||
|
||||
option(MUJOCO_SAMPLES_USE_SYSTEM_MUJOCO "Use installed MuJoCo version."
|
||||
${DEFAULT_USE_SYSTEM_MUJOCO}
|
||||
)
|
||||
unset(DEFAULT_USE_SYSTEM_MUJOCO)
|
||||
|
||||
option(MUJOCO_SAMPLES_USE_SYSTEM_MUJOCO "Use installed MuJoCo version." OFF)
|
||||
option(MUJOCO_SAMPLES_USE_SYSTEM_GLFW "Use installed GLFW version." OFF)
|
||||
|
||||
set(MUJOCO_DEP_VERSION_glfw
|
||||
7d5a16ce714f0b5f4efa3262de22e4d948851525 # 3.3.6
|
||||
CACHE STRING "Version of `glfw` to be fetched."
|
||||
)
|
||||
mark_as_advanced(MUJOCO_DEP_VERSION_glfw)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
set(MUJOCO_BUILD_EXAMPLES OFF)
|
||||
set(MUJOCO_BUILD_TESTS OFF)
|
||||
set(MUJOCO_BUILD_PYTHON OFF)
|
||||
set(MUJOCO_TEST_PYTHON_UTIL OFF)
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
MUJOCO_SAMPLES_USE_SYSTEM_MUJOCO
|
||||
PACKAGE_NAME
|
||||
mujoco
|
||||
LIBRARY_NAME
|
||||
mujoco
|
||||
GIT_REPO
|
||||
https://github.com/deepmind/mujoco.git
|
||||
GIT_TAG
|
||||
main
|
||||
TARGETS
|
||||
mujoco
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
option(MUJOCO_SAMPLES_STATIC_GLFW "Link MuJoCo sample apps against GLFW statically." ON)
|
||||
if(MUJOCO_SAMPLES_STATIC_GLFW)
|
||||
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS
|
||||
OFF
|
||||
CACHE INTERNAL "Build SHARED libraries"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(GLFW_BUILD_EXAMPLES OFF)
|
||||
set(GLFW_BUILD_TESTS OFF)
|
||||
set(GLFW_BUILD_DOCS OFF)
|
||||
set(GLFW_INSTALL OFF)
|
||||
|
||||
findorfetch(
|
||||
USE_SYSTEM_PACKAGE
|
||||
MUJOCO_SAMPLES_USE_SYSTEM_GLFW
|
||||
PACKAGE_NAME
|
||||
glfw
|
||||
LIBRARY_NAME
|
||||
glfw
|
||||
GIT_REPO
|
||||
https://github.com/glfw/glfw.git
|
||||
GIT_TAG
|
||||
${MUJOCO_DEP_VERSION_glfw}
|
||||
TARGETS
|
||||
glfw
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
if(MUJOCO_SAMPLES_STATIC_GLFW)
|
||||
set(BUILD_SHARED_LIBS
|
||||
${BUILD_SHARED_LIBS_OLD}
|
||||
CACHE BOOL "Build SHARED libraries" FORCE
|
||||
)
|
||||
unset(BUILD_SHARED_LIBS_OLD)
|
||||
endif()
|
||||
|
||||
if(NOT SAMPLE_STANDALONE)
|
||||
target_compile_options(glfw PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
|
||||
target_link_options(glfw PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
|
||||
endif()
|
||||
@@ -0,0 +1,106 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Global compilation settings
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # For LLVM tooling
|
||||
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to 'Release' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"Release"
|
||||
CACHE STRING "Choose the type of build, recommanded options are: Debug or Release" FORCE
|
||||
)
|
||||
endif()
|
||||
set(BUILD_TYPES
|
||||
"Debug"
|
||||
"Release"
|
||||
"MinSizeRel"
|
||||
"RelWithDebInfo"
|
||||
)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${BUILD_TYPES})
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Change the default output directory in the build structure. This is not stricly needed, but helps
|
||||
# running in Windows, such that all built executables have DLLs in the same folder as the .exe
|
||||
# files.
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/Gy /Gw /Oi)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-fdata-sections -ffunction-sections)
|
||||
endif()
|
||||
|
||||
# We default to shared library.
|
||||
set(BUILD_SHARED_LIBS
|
||||
ON
|
||||
CACHE BOOL "Build Mujoco as shared library."
|
||||
)
|
||||
|
||||
option(MUJOCO_ENABLE_AVX "Build binaries that require AVX instructions, if possible." ON)
|
||||
option(MUJOCO_ENABLE_AVX_INTRINSICS "Make use of hand-written AVX intrinsics, if possible." ON)
|
||||
option(MUJOCO_ENABLE_RPATH "Enable RPath support when installing Mujoco." ON)
|
||||
mark_as_advanced(MUJOCO_ENABLE_RPATH)
|
||||
|
||||
if(MUJOCO_ENABLE_AVX)
|
||||
include(CheckAvxSupport)
|
||||
get_avx_compile_options(AVX_COMPILE_OPTIONS)
|
||||
else()
|
||||
set(AVX_COMPILE_OPTIONS)
|
||||
endif()
|
||||
|
||||
option(MUJOCO_BUILD_MACOS_FRAMEWORKS "Build libraries as macOS Frameworks" OFF)
|
||||
|
||||
# Get some extra link options.
|
||||
include(MujocoLinkOptions)
|
||||
get_mujoco_extra_link_options(EXTRA_LINK_OPTIONS)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC))
|
||||
set(EXTRA_COMPILE_OPTIONS -Wall -Werror)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(EXTRA_COMPILE_OPTIONS
|
||||
-Wno-int-in-bool-context
|
||||
-Wno-maybe-uninitialized
|
||||
-Wno-sign-compare
|
||||
-Wno-stringop-overflow
|
||||
-Wno-stringop-truncation
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include(MujocoHarden)
|
||||
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
// help
|
||||
const char helpstring[] =
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
// enable compilation with and without OpenMP support
|
||||
#if defined(_OPENMP)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2022 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
std::string getSavePath(const char* filename) {
|
||||
NSSavePanel* panel = [NSSavePanel savePanel];
|
||||
NSURL* userDocumentsDir = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory
|
||||
inDomains:NSUserDomainMask].firstObject;
|
||||
[panel setDirectoryURL:userDocumentsDir];
|
||||
[panel setNameFieldStringValue:[NSString stringWithUTF8String:filename]];
|
||||
if ([panel runModal] == NSModalResponseOK) {
|
||||
std::ostringstream s;
|
||||
s << [panel.URL.path cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
return s.str();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
// select EGL, OSMESA or GLFW
|
||||
#if defined(MJ_EGL)
|
||||
|
||||
+27
-4
@@ -19,7 +19,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include "uitools.h"
|
||||
|
||||
#include "array_safety.h"
|
||||
@@ -1289,6 +1289,21 @@ void uiLayout(mjuiState* state) {
|
||||
|
||||
|
||||
|
||||
// When launched via an App Bundle on macOS, the working directory is the path to the App Bundle's
|
||||
// resource directory. This causes files to be saved into the bundle, which is not the desired
|
||||
// behavior. Instead, we open a save dialog box to ask the user where to put the file.
|
||||
// Since the dialog box logic needs to be written in Objective-C, we separate it into a different
|
||||
// source file.
|
||||
#ifdef __APPLE__
|
||||
std::string getSavePath(const char* filename);
|
||||
#else
|
||||
static std::string getSavePath(const char* filename) {
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// handle UI event
|
||||
void uiEvent(mjuiState* state) {
|
||||
int i;
|
||||
@@ -1305,13 +1320,21 @@ void uiEvent(mjuiState* state) {
|
||||
if (it && it->sectionid==SECT_FILE) {
|
||||
switch (it->itemid) {
|
||||
case 0: // Save xml
|
||||
if (!mj_saveLastXML("mjmodel.xml", m, err, 200)) {
|
||||
std::printf("Save XML error: %s", err);
|
||||
{
|
||||
const std::string path = getSavePath("mjmodel.xml");
|
||||
if (!path.empty() && !mj_saveLastXML(path.c_str(), m, err, 200)) {
|
||||
std::printf("Save XML error: %s", err);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Save mjb
|
||||
mj_saveModel(m, "mjmodel.mjb", NULL, 0);
|
||||
{
|
||||
const std::string path = getSavePath("mjmodel.mjb");
|
||||
if (!path.empty()) {
|
||||
mj_saveModel(m, path.c_str(), NULL, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Print model
|
||||
|
||||
+3
-2
@@ -18,7 +18,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
|
||||
// maximum number of threads
|
||||
@@ -94,7 +94,8 @@ void simulate(int id, int nstep, mjtNum ctrlnoise) {
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv) {
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// print help if arguments are missing
|
||||
if (argc<2 || argc>6) {
|
||||
return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <mjxmacro.h>
|
||||
#include <mujoco.h>
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
#include "array_safety.h"
|
||||
namespace mju = ::mujoco::sample_util;
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
#define MUJOCO_UITOOLS_H_
|
||||
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include <mujoco.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
// this is a C-API
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_CC_ARRAY_SAFETY_H_
|
||||
#define MUJOCO_SRC_CC_ARRAY_SAFETY_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
// Provides safe alternatives to the sizeof() operator and standard library functions for handling
|
||||
// null-terminated (C-style) strings in raw char arrays.
|
||||
//
|
||||
// These functions make use of compile-time array sizes to limit read and write operations to within
|
||||
// the array bounds. They are designed to trigger a compile error if the array size cannot be
|
||||
// determined at compile time (e.g. when an array has decayed into a pointer).
|
||||
//
|
||||
// They do not perform runtime bound checks.
|
||||
|
||||
namespace mujoco {
|
||||
namespace util {
|
||||
|
||||
// returns sizeof(arr)
|
||||
// use instead of sizeof() to avoid unintended array-to-pointer decay
|
||||
template <typename T, int N>
|
||||
static constexpr std::size_t sizeof_arr(const T(&arr)[N]) {
|
||||
return sizeof(arr);
|
||||
}
|
||||
|
||||
// like std::strcmp but it will not read beyond the bound of either lhs or rhs
|
||||
template <std::size_t N1, std::size_t N2>
|
||||
static inline int strcmp_arr(const char (&lhs)[N1], const char (&rhs)[N2]) {
|
||||
return std::strncmp(lhs, rhs, std::min(N1, N2));
|
||||
}
|
||||
|
||||
// like std::strlen but it will not read beyond the bound of str
|
||||
// if str is not null-terminated, returns sizeof(str)
|
||||
template <std::size_t N>
|
||||
static inline std::size_t strlen_arr(const char (&str)[N]) {
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
if (str[i] == '\0') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return N;
|
||||
}
|
||||
|
||||
// like std::sprintf but will not write beyond the bound of dest
|
||||
// dest is guaranteed to be null-terminated
|
||||
template <std::size_t N>
|
||||
static inline int sprintf_arr(char (&dest)[N], const char* format, ...) {
|
||||
std::va_list vargs;
|
||||
va_start(vargs, format);
|
||||
int retval = std::vsnprintf(dest, N, format, vargs);
|
||||
va_end(vargs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// like std::strcat but will not write beyond the bound of dest
|
||||
// dest is guaranteed to be null-terminated
|
||||
template <std::size_t N>
|
||||
static inline char* strcat_arr(char (&dest)[N], const char* src) {
|
||||
return std::strncat(dest, src, sizeof_arr(dest) - strlen_arr(dest) - 1);
|
||||
}
|
||||
|
||||
// like std::strcpy but won't write beyond the bound of dest
|
||||
// dest is guaranteed to be null-terminated
|
||||
template <std::size_t N>
|
||||
static inline char* strcpy_arr(char (&dest)[N], const char* src) {
|
||||
{
|
||||
std::size_t i = 0;
|
||||
for (; src[i] && i < N - 1; ++i) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
dest[i] = '\0';
|
||||
}
|
||||
return &dest[0];
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mujoco
|
||||
|
||||
#endif // MUJOCO_SRC_CC_ARRAY_SAFETY_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
# Copyright 2021 DeepMind Technologies Limited
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(MUJOCO_ENGINE_SRCS
|
||||
engine_array_safety.h
|
||||
engine_callback.c
|
||||
engine_callback.h
|
||||
engine_collision_box.c
|
||||
engine_collision_convex.c
|
||||
engine_collision_convex.h
|
||||
engine_collision_driver.c
|
||||
engine_collision_driver.h
|
||||
engine_collision_primitive.c
|
||||
engine_collision_primitive.h
|
||||
engine_core_constraint.c
|
||||
engine_core_constraint.h
|
||||
engine_core_smooth.c
|
||||
engine_core_smooth.h
|
||||
engine_crossplatform.h
|
||||
engine_file.c
|
||||
engine_file.h
|
||||
engine_forward.c
|
||||
engine_forward.h
|
||||
engine_inverse.c
|
||||
engine_inverse.h
|
||||
engine_io.c
|
||||
engine_io.h
|
||||
engine_macro.h
|
||||
engine_print.c
|
||||
engine_print.h
|
||||
engine_ray.c
|
||||
engine_ray.h
|
||||
engine_sensor.c
|
||||
engine_sensor.h
|
||||
engine_setconst.c
|
||||
engine_setconst.h
|
||||
engine_solver.c
|
||||
engine_solver.h
|
||||
engine_support.c
|
||||
engine_support.h
|
||||
engine_util_blas.c
|
||||
engine_util_blas.h
|
||||
engine_util_errmem.c
|
||||
engine_util_errmem.h
|
||||
engine_util_misc.c
|
||||
engine_util_misc.h
|
||||
engine_util_solve.c
|
||||
engine_util_solve.h
|
||||
engine_util_sparse.c
|
||||
engine_util_sparse.h
|
||||
engine_util_spatial.c
|
||||
engine_util_spatial.h
|
||||
engine_vfs.c
|
||||
engine_vfs.h
|
||||
engine_vis_init.c
|
||||
engine_vis_init.h
|
||||
engine_vis_interact.c
|
||||
engine_vis_interact.h
|
||||
engine_vis_visualize.c
|
||||
engine_vis_visualize.h
|
||||
)
|
||||
|
||||
target_sources(mujoco PRIVATE ${MUJOCO_ENGINE_SRCS})
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_ARRAY_SAFETY_H_
|
||||
#define MUJOCO_SRC_ENGINE_ENGINE_ARRAY_SAFETY_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Evaluates to sizeof(arr) if arr is a char array, and emits a compiler error
|
||||
// otherwise. In particular, emits a compiler error if arr is a char*.
|
||||
#define mjSIZEOFARRAY(arr) _Generic(&(arr), char(*)[sizeof(arr)]: sizeof(arr))
|
||||
|
||||
#define mjSNPRINTF(dest, ...) snprintf(dest, mjSIZEOFARRAY(dest), __VA_ARGS__)
|
||||
|
||||
#define mjSTRNCAT(dest, src) strncat(dest, src, mjSIZEOFARRAY(dest) - strlen(dest) - 1)
|
||||
|
||||
#define mjSTRNCPY(dest, src) mju_strncpy(dest, src, mjSIZEOFARRAY(dest))
|
||||
|
||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_ARRAY_SAFETY_H_
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "engine/engine_callback.h"
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
|
||||
//------------------------- global callback pointers -----------------------------------------------
|
||||
|
||||
mjfGeneric mjcb_passive = 0;
|
||||
mjfGeneric mjcb_control = 0;
|
||||
mjfConFilt mjcb_contactfilter = 0;
|
||||
mjfSensor mjcb_sensor = 0;
|
||||
mjfTime mjcb_time = 0;
|
||||
mjfAct mjcb_act_bias = 0;
|
||||
mjfAct mjcb_act_gain = 0;
|
||||
mjfAct mjcb_act_dyn = 0;
|
||||
|
||||
|
||||
|
||||
// reset callbacks to defauls
|
||||
void mj_resetCallbacks(void) {
|
||||
mjcb_passive = 0;
|
||||
mjcb_control = 0;
|
||||
mjcb_contactfilter = 0;
|
||||
mjcb_sensor = 0;
|
||||
mjcb_time = 0;
|
||||
mjcb_act_bias = 0;
|
||||
mjcb_act_gain = 0;
|
||||
mjcb_act_dyn = 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_CALLBACK_H_
|
||||
#define MUJOCO_SRC_ENGINE_ENGINE_CALLBACK_H_
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjexport.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// global callback function pointers
|
||||
MJAPI extern mjfGeneric mjcb_passive;
|
||||
MJAPI extern mjfGeneric mjcb_control;
|
||||
MJAPI extern mjfConFilt mjcb_contactfilter;
|
||||
MJAPI extern mjfSensor mjcb_sensor;
|
||||
MJAPI extern mjfTime mjcb_time;
|
||||
MJAPI extern mjfAct mjcb_act_bias;
|
||||
MJAPI extern mjfAct mjcb_act_gain;
|
||||
MJAPI extern mjfAct mjcb_act_dyn;
|
||||
|
||||
|
||||
// reset callbacks to defaults
|
||||
MJAPI void mj_resetCallbacks(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_CALLBACK_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_COLLISION_CONVEX_H_
|
||||
#define MUJOCO_SRC_ENGINE_ENGINE_COLLISION_CONVEX_H_
|
||||
|
||||
// libCCD has an unconditional `#define _CRT_SECURE_NO_WARNINGS` on Windows.
|
||||
// TODO(stunya): Remove once https://github.com/danfis/libccd/pull/77 is merged
|
||||
#ifdef _CRT_SECURE_NO_WARNINGS
|
||||
#undef _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <ccd/vec3.h>
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ccd general object type
|
||||
struct _mjtCCD {
|
||||
const mjModel* model;
|
||||
const mjData* data;
|
||||
int geom;
|
||||
int meshindex;
|
||||
mjtNum margin;
|
||||
mjtNum rotate[4];
|
||||
};
|
||||
typedef struct _mjtCCD mjtCCD;
|
||||
|
||||
|
||||
// ccd support function
|
||||
void mjccd_support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec);
|
||||
|
||||
|
||||
// pairwise collision functions using ccd
|
||||
int mjc_PlaneConvex (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_ConvexHField (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_Convex (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
|
||||
|
||||
// fix contact frame normal
|
||||
void mjc_fixNormal(const mjModel* m, const mjData* d, mjContact* con, int g1, int g2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_COLLISION_CONVEX_H_
|
||||
@@ -0,0 +1,784 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "engine/engine_collision_driver.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include "engine/engine_callback.h"
|
||||
#include "engine/engine_collision_convex.h"
|
||||
#include "engine/engine_collision_primitive.h"
|
||||
#include "engine/engine_core_constraint.h"
|
||||
#include "engine/engine_crossplatform.h"
|
||||
#include "engine/engine_io.h"
|
||||
#include "engine/engine_macro.h"
|
||||
#include "engine/engine_util_blas.h"
|
||||
#include "engine/engine_util_errmem.h"
|
||||
#include "engine/engine_util_misc.h"
|
||||
#include "engine/engine_util_solve.h"
|
||||
#include "engine/engine_util_spatial.h"
|
||||
|
||||
// table of pair-wise collision functions
|
||||
mjfCollision mjCOLLISIONFUNC[mjNGEOMTYPES][mjNGEOMTYPES] = {
|
||||
|
||||
/* PLANE HFIELD SPHERE CAPSULE ELLIPSOID CYLINDER BOX MESH */
|
||||
/*PLANE */ {0, 0, mjc_PlaneSphere, mjc_PlaneCapsule, mjc_PlaneConvex, mjc_PlaneCylinder, mjc_PlaneBox, mjc_PlaneConvex},
|
||||
/*HFIELD */ {0, 0, mjc_ConvexHField, mjc_ConvexHField, mjc_ConvexHField, mjc_ConvexHField, mjc_ConvexHField, mjc_ConvexHField},
|
||||
/*SHPERE */ {0, 0, mjc_SphereSphere, mjc_SphereCapsule, mjc_Convex, mjc_Convex, mjc_SphereBox, mjc_Convex},
|
||||
/*CAPSULE */ {0, 0, 0, mjc_CapsuleCapsule, mjc_Convex, mjc_Convex, mjc_CapsuleBox, mjc_Convex},
|
||||
/*ELLIPSOID */ {0, 0, 0, 0, mjc_Convex, mjc_Convex, mjc_Convex, mjc_Convex},
|
||||
/*CYLINDER */ {0, 0, 0, 0, 0, mjc_Convex, mjc_Convex, mjc_Convex},
|
||||
/*BOX */ {0, 0, 0, 0, 0, 0, mjc_BoxBox, mjc_Convex},
|
||||
/*MESH */ {0, 0, 0, 0, 0, 0, 0, mjc_Convex}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------- collision detection entry point ------------------------------------
|
||||
|
||||
void mj_collision(const mjModel* m, mjData* d) {
|
||||
int g1, g2, signature, merged, b1 = 0, b2 = 0, exadr = 0, pairadr = 0, startadr;
|
||||
int nexclude = m->nexclude, npair = m->npair, nbodypair = ((m->nbody-1)*m->nbody)/2;
|
||||
int *broadphasepair = 0;
|
||||
mjMARKSTACK;
|
||||
|
||||
// clear size
|
||||
d->ncon = 0;
|
||||
|
||||
// return if disabled
|
||||
if (mjDISABLED(mjDSBL_CONSTRAINT) || mjDISABLED(mjDSBL_CONTACT)
|
||||
|| m->nconmax==0 || m->nbody < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// predefined only; ignore exclude
|
||||
if (m->opt.collision==mjCOL_PAIR) {
|
||||
for (pairadr=0; pairadr<npair; pairadr++) {
|
||||
mj_collideGeoms(m, d, pairadr, -1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// dynamic only or merge; apply exclude
|
||||
else {
|
||||
// call broadphase collision detector
|
||||
broadphasepair = (int*)mj_stackAlloc(d, (m->nbody*(m->nbody-1))/2);
|
||||
nbodypair = mj_broadphase(m, d, broadphasepair, (m->nbody*(m->nbody-1))/2);
|
||||
|
||||
// loop over body pairs (broadphase or all)
|
||||
for (int i=0; i<nbodypair; i++) {
|
||||
// reconstruct body pair ids
|
||||
b1 = (broadphasepair[i]>>16) & 0xFFFF;
|
||||
b2 = broadphasepair[i] & 0xFFFF;
|
||||
|
||||
// compute signature for this body pair
|
||||
signature = ((b1+1)<<16) + (b2+1);
|
||||
|
||||
// merge predefined pairs
|
||||
merged = 0;
|
||||
startadr = pairadr;
|
||||
if (npair && m->opt.collision==mjCOL_ALL) {
|
||||
// test all predefined pairs for which pair_signature<=signature
|
||||
while (pairadr<npair && m->pair_signature[pairadr]<=signature) {
|
||||
if (m->pair_signature[pairadr]==signature) {
|
||||
merged = 1;
|
||||
}
|
||||
mj_collideGeoms(m, d, pairadr++, -1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// handle exclusion
|
||||
if (nexclude) {
|
||||
// advance exadr while exclude_signature < signature
|
||||
while (m->exclude_signature[exadr]<signature && exadr<nexclude) {
|
||||
exadr++;
|
||||
}
|
||||
|
||||
// skip this body pair if its signature is found in exclude array
|
||||
if (exadr<nexclude && m->exclude_signature[exadr]==signature) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// test all geom pairs within this body pair
|
||||
if (m->body_geomnum[b1] && m->body_geomnum[b2]) {
|
||||
for (g1=m->body_geomadr[b1]; g1<m->body_geomadr[b1]+m->body_geomnum[b1]; g1++) {
|
||||
for (g2=m->body_geomadr[b2]; g2<m->body_geomadr[b2]+m->body_geomnum[b2]; g2++) {
|
||||
// merged: make sure geom pair is not repeated
|
||||
if (merged) {
|
||||
// find matching pair
|
||||
int found = 0;
|
||||
for (int k=startadr; k<pairadr; k++) {
|
||||
if ((m->pair_geom1[k]==g1 && m->pair_geom2[k]==g2) ||
|
||||
(m->pair_geom1[k]==g2 && m->pair_geom2[k]==g1)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not found: test
|
||||
if (!found) {
|
||||
mj_collideGeoms(m, d, g1, g2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// not merged: always test
|
||||
else {
|
||||
mj_collideGeoms(m, d, g1, g2, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finish merging predefined pairs
|
||||
if (npair && m->opt.collision==mjCOL_ALL)
|
||||
while (pairadr<npair) {
|
||||
mj_collideGeoms(m, d, pairadr++, -1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mjFREESTACK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------- broad-phase collision detection ------------------------------------
|
||||
|
||||
// helper structure for SAP sorting
|
||||
struct _mjtBroadphase {
|
||||
float value;
|
||||
int body_ismax;
|
||||
};
|
||||
typedef struct _mjtBroadphase mjtBroadphase;
|
||||
|
||||
|
||||
// make AABB for one body
|
||||
static void makeAABB(const mjModel* m, mjData* d, mjtNum* aabb, int body, const mjtNum* frame) {
|
||||
int geom;
|
||||
mjtNum _aabb[6], cen;
|
||||
|
||||
// no geoms attached to body: set to 0
|
||||
if (m->body_geomnum[body]==0) {
|
||||
mju_zero(aabb, 6);
|
||||
return;
|
||||
}
|
||||
|
||||
// process all body geoms
|
||||
for (int i=0; i<m->body_geomnum[body]; i++) {
|
||||
// get geom id
|
||||
geom = m->body_geomadr[body]+i;
|
||||
|
||||
// set _aabb for this geom
|
||||
for (int j=0; j<3; j++) {
|
||||
cen = mju_dot3(d->geom_xpos+3*geom, frame+3*j);
|
||||
_aabb[2*j] = cen - m->geom_rbound[geom] - m->geom_margin[geom];
|
||||
_aabb[2*j+1] = cen + m->geom_rbound[geom] + m->geom_margin[geom];
|
||||
}
|
||||
|
||||
// update body aabb
|
||||
if (i==0) {
|
||||
mju_copy(aabb, _aabb, 6);
|
||||
} else {
|
||||
for (int j=0; j<3; j++) {
|
||||
aabb[2*j] = mju_min(aabb[2*j], _aabb[2*j]);
|
||||
aabb[2*j+1] = mju_max(aabb[2*j+1], _aabb[2*j+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return 1 if body has plane or hfield geom, 0 otherwise
|
||||
static int has_plane_or_hfield(const mjModel* m, int body) {
|
||||
int start = m->body_geomadr[body];
|
||||
int end = m->body_geomadr[body] + m->body_geomnum[body];
|
||||
|
||||
// scan geoms belonging to body
|
||||
int g;
|
||||
for (g=start; g<end; g++) {
|
||||
if (m->geom_type[g]==mjGEOM_PLANE || m->geom_type[g]==mjGEOM_HFIELD) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// add body pair in buffer
|
||||
static void add_pair(const mjModel* m, int b1, int b2, int* npair, int* pair, int maxpair) {
|
||||
// add pair if there is room in buffer
|
||||
if ((*npair)<maxpair) {
|
||||
// exlude based on contype and conaffinity
|
||||
if (m && m->body_geomnum[b1]==1 && m->body_geomnum[b2]==1) {
|
||||
// get contypes and conaffinities
|
||||
int contype1 = m->geom_contype[m->body_geomadr[b1]];
|
||||
int conaffinity1 = m->geom_conaffinity[m->body_geomadr[b1]];
|
||||
int contype2 = m->geom_contype[m->body_geomadr[b2]];
|
||||
int conaffinity2 = m->geom_conaffinity[m->body_geomadr[b2]];
|
||||
|
||||
// compatibility check
|
||||
if (!(contype1 & conaffinity2) && !(contype2 & conaffinity1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add pair
|
||||
if (b1<b2) {
|
||||
pair[*npair] = (b1<<16) + b2;
|
||||
} else {
|
||||
pair[*npair] = (b2<<16) + b1;
|
||||
}
|
||||
|
||||
(*npair)++;
|
||||
} else {
|
||||
mju_error("Broadphase buffer full");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// comparison function for broadphase
|
||||
quicksortfunc(broadcompare, context, el1, el2) {
|
||||
mjtBroadphase* b1 = (mjtBroadphase*)el1;
|
||||
mjtBroadphase* b2 = (mjtBroadphase*)el2;
|
||||
|
||||
if (b1->value<b2->value) {
|
||||
return -1;
|
||||
} else if (b1->value==b2->value) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// comparison function for pair sorting
|
||||
quicksortfunc(paircompare, context, el1, el2) {
|
||||
int signature1 = *(int*)el1;
|
||||
int signature2 = *(int*)el2;
|
||||
|
||||
if (signature1<signature2) {
|
||||
return -1;
|
||||
} else if (signature1==signature2) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// does body have collidable geoms
|
||||
static int can_collide(const mjModel* m, int b) {
|
||||
int g;
|
||||
|
||||
// scan geoms; return if collidable
|
||||
for (g=0; g<m->body_geomnum[b]; g++) {
|
||||
int ind = m->body_geomadr[b] + g;
|
||||
if (m->geom_contype[ind] || m->geom_conaffinity[ind]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// none found
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// broadphase collision detector
|
||||
int mj_broadphase(const mjModel* m, mjData* d, int* pair, int maxpair) {
|
||||
int i, j, b1, b2, toremove, cnt, npair = 0, nbody = m->nbody, ngeom = m->ngeom;
|
||||
mjtNum cov[9], cen[3], dif[3], eigval[3], frame[9], quat[4];
|
||||
mjtBroadphase *sortbuf, *activebuf;
|
||||
mjtNum *aabb;
|
||||
mjMARKSTACK;
|
||||
|
||||
// world with geoms, and body with plane or hfield, can collide all bodies
|
||||
for (b1=0; b1<nbody; b1++) {
|
||||
// cannot colide
|
||||
if (!can_collide(m, b1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// world with geoms, or welded body with plane or hfield
|
||||
if ((b1==0 && m->body_geomnum[b1]>0) || (m->body_weldid[b1]==0 && has_plane_or_hfield(m, b1))) {
|
||||
for (b2=0; b2<nbody; b2++) {
|
||||
if (b1!=b2) {
|
||||
add_pair(NULL, b1, b2, &npair, pair, maxpair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find center of non-world geoms; return if none
|
||||
cnt = 0;
|
||||
mju_zero3(cen);
|
||||
for (i=0; i<ngeom; i++) {
|
||||
if (m->geom_bodyid[i]) {
|
||||
mju_addTo3(cen, d->geom_xpos+3*i);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt==0) {
|
||||
return npair;
|
||||
} else {
|
||||
for (i=0; i<3; i++) {
|
||||
cen[i] /= cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// compute covariance
|
||||
mju_zero(cov, 9);
|
||||
for (i=0; i<ngeom; i++) {
|
||||
if (m->geom_bodyid[i]) {
|
||||
mju_sub3(dif, d->geom_xpos+3*i, cen);
|
||||
mjtNum D00 = dif[0]*dif[0];
|
||||
mjtNum D01 = dif[0]*dif[1];
|
||||
mjtNum D02 = dif[0]*dif[2];
|
||||
mjtNum D11 = dif[1]*dif[1];
|
||||
mjtNum D12 = dif[1]*dif[2];
|
||||
mjtNum D22 = dif[2]*dif[2];
|
||||
cov[0] += D00;
|
||||
cov[1] += D01;
|
||||
cov[2] += D02;
|
||||
cov[3] += D01;
|
||||
cov[4] += D11;
|
||||
cov[5] += D12;
|
||||
cov[6] += D02;
|
||||
cov[7] += D12;
|
||||
cov[8] += D22;
|
||||
}
|
||||
}
|
||||
for (i=0; i<9; i++) {
|
||||
cov[i] /= cnt;
|
||||
}
|
||||
|
||||
// construct covariance-aligned 3D frame
|
||||
mju_eig3(eigval, frame, quat, cov);
|
||||
|
||||
// allocate AABB; clear world entry (not used)
|
||||
aabb = mj_stackAlloc(d, 6*nbody);
|
||||
mju_zero(aabb, 6);
|
||||
|
||||
// construct body AABB for the aligned frame, count collidable
|
||||
int bufcnt = 0;
|
||||
for (i=1; i<nbody; i++) {
|
||||
makeAABB(m, d, aabb+6*i, i, frame);
|
||||
|
||||
if (can_collide(m, i)) {
|
||||
bufcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing collidable
|
||||
if (!bufcnt) {
|
||||
goto endbroad;
|
||||
}
|
||||
|
||||
// allocate sort buffer
|
||||
i = sizeof(mjtBroadphase)/sizeof(mjtNum);
|
||||
j = sizeof(mjtBroadphase)%sizeof(mjtNum);
|
||||
sortbuf = (mjtBroadphase*)mj_stackAlloc(d, 2*bufcnt*(i + (j ? 1 : 0)));
|
||||
activebuf = (mjtBroadphase*)mj_stackAlloc(d, 2*bufcnt*(i + (j ? 1 : 0)));
|
||||
|
||||
// init sortbuf with axis0
|
||||
j = 0;
|
||||
for (i=1; i<nbody; i++) {
|
||||
// cannot colide
|
||||
if (!can_collide(m, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// init
|
||||
sortbuf[2*j].body_ismax = i;
|
||||
sortbuf[2*j].value = (float)aabb[6*i];
|
||||
sortbuf[2*j+1].body_ismax = i + 0x10000;
|
||||
sortbuf[2*j+1].value = (float)aabb[6*i+1];
|
||||
j++;
|
||||
}
|
||||
|
||||
// sanity check; SHOULD NOT OCCUR
|
||||
if (j!=bufcnt) {
|
||||
mju_error("Internal error in broadphase: unexpected bufcnt");
|
||||
}
|
||||
|
||||
// sort along axis0
|
||||
mjQUICKSORT(sortbuf, 2*bufcnt, sizeof(mjtBroadphase), broadcompare, 0);
|
||||
|
||||
// sweep and prune
|
||||
cnt = 0; // size of active list
|
||||
for (i=0; i<2*bufcnt; i++) {
|
||||
// min value: collide with all in list, add
|
||||
if (!(sortbuf[i].body_ismax & 0x10000)) {
|
||||
for (j=0; j<cnt; j++) {
|
||||
// get body ids
|
||||
b1 = activebuf[j].body_ismax;
|
||||
b2 = sortbuf[i].body_ismax;
|
||||
|
||||
// use the other two axes to prune if possible
|
||||
if (aabb[6*b1+2] > aabb[6*b2+3] ||
|
||||
aabb[6*b1+3] < aabb[6*b2+2] ||
|
||||
aabb[6*b1+4] > aabb[6*b2+5] ||
|
||||
aabb[6*b1+5] < aabb[6*b2+4]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add body pair if there is room in buffer
|
||||
add_pair(m, b1, b2, &npair, pair, maxpair);
|
||||
}
|
||||
|
||||
// add to list
|
||||
activebuf[cnt] = sortbuf[i];
|
||||
cnt++;
|
||||
}
|
||||
|
||||
// max value: remove corresponding min value from list
|
||||
else {
|
||||
toremove = sortbuf[i].body_ismax & 0xFFFF;
|
||||
for (j=0; j<cnt; j++) {
|
||||
if (activebuf[j].body_ismax==toremove) {
|
||||
if (j<cnt-1) {
|
||||
memmove(activebuf+j, activebuf+j+1, sizeof(mjtBroadphase)*(cnt-1-j));
|
||||
}
|
||||
cnt--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endbroad:
|
||||
|
||||
// sort pairs by signature
|
||||
if (npair) {
|
||||
mjQUICKSORT(pair, npair, sizeof(int), paircompare, 0);
|
||||
}
|
||||
|
||||
mjFREESTACK;
|
||||
return npair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------- narrow-phase collision detection -----------------------------------
|
||||
|
||||
// plane : geom_center distance, assuming g1 is plane
|
||||
static mjtNum plane_geom(const mjModel* m, mjData* d, int g1, int g2) {
|
||||
mjtNum* mat1 = d->geom_xmat + 9*g1;
|
||||
mjtNum norm[3] = {mat1[2], mat1[5], mat1[8]};
|
||||
mjtNum dif[3];
|
||||
|
||||
mju_sub3(dif, d->geom_xpos + 3*g2, d->geom_xpos + 3*g1);
|
||||
return mju_dot3(dif, norm);
|
||||
}
|
||||
|
||||
|
||||
// test two geoms for collision, apply filters, add to contact list
|
||||
// flg_user disables filters and uses usermargin
|
||||
void mj_collideGeoms(const mjModel* m, mjData* d, int g1, int g2, int flg_user, mjtNum usermargin) {
|
||||
int i, num, type1, type2, b1, b2, weld1, weld2, condim;
|
||||
mjtNum margin, gap, mix, friction[5], solref[mjNREF], solimp[mjNIMP];
|
||||
mjContact con[mjMAXCONPAIR];
|
||||
int ipair = (g2<0 ? g1 : -1);
|
||||
|
||||
// get explicit geom ids from pair
|
||||
if (ipair>=0) {
|
||||
g1 = m->pair_geom1[ipair];
|
||||
g2 = m->pair_geom2[ipair];
|
||||
}
|
||||
|
||||
// order geoms by type
|
||||
if (m->geom_type[g1] > m->geom_type[g2]) {
|
||||
i = g1;
|
||||
g1 = g2;
|
||||
g2 = i;
|
||||
}
|
||||
|
||||
// copy types and bodies
|
||||
type1 = m->geom_type[g1];
|
||||
type2 = m->geom_type[g2];
|
||||
b1 = m->geom_bodyid[g1];
|
||||
b2 = m->geom_bodyid[g2];
|
||||
weld1 = m->body_weldid[b1];
|
||||
weld2 = m->body_weldid[b2];
|
||||
|
||||
// return if no collision function
|
||||
if (!mjCOLLISIONFUNC[type1][type2]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// apply filters if not predefined pair and not flg_user
|
||||
if (ipair<0 && !flg_user) {
|
||||
// user filter if defined
|
||||
if (mjcb_contactfilter) {
|
||||
if (mjcb_contactfilter(m, d, g1, g2)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise built-in filter
|
||||
else if (mj_contactFilter(
|
||||
type1, m->geom_contype[g1], m->geom_conaffinity[g1],
|
||||
weld1, m->body_weldid[m->body_parentid[weld1]],
|
||||
type2, m->geom_contype[g2], m->geom_conaffinity[g2],
|
||||
weld2, m->body_weldid[m->body_parentid[weld2]],
|
||||
!mjDISABLED(mjDSBL_FILTERPARENT) && weld1 && weld2)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// set margin, gap, condim: dynamic
|
||||
if (ipair<0) {
|
||||
// margin and gap: max
|
||||
margin = mju_max(m->geom_margin[g1], m->geom_margin[g2]);
|
||||
gap = mju_max(m->geom_gap[g1], m->geom_gap[g2]);
|
||||
|
||||
// condim: priority or max
|
||||
if (m->geom_priority[g1]!=m->geom_priority[g2]) {
|
||||
int gp = (m->geom_priority[g1]>m->geom_priority[g2] ? g1 : g2);
|
||||
condim = m->geom_condim[gp];
|
||||
} else {
|
||||
condim = mjMAX(m->geom_condim[g1], m->geom_condim[g2]);
|
||||
}
|
||||
}
|
||||
|
||||
// set margin, gap, condim: pair
|
||||
else {
|
||||
margin = m->pair_margin[ipair];
|
||||
gap = m->pair_gap[ipair];
|
||||
condim = m->pair_dim[ipair];
|
||||
}
|
||||
|
||||
// adjust margin
|
||||
if (flg_user) {
|
||||
margin = usermargin;
|
||||
} else {
|
||||
margin = mj_assignMargin(m, margin);
|
||||
}
|
||||
|
||||
// bounding sphere filter
|
||||
if (m->geom_rbound[g1]>0 && m->geom_rbound[g2]>0 &&
|
||||
(mju_dist3(d->geom_xpos+3*g1, d->geom_xpos+3*g2) >
|
||||
m->geom_rbound[g1] + m->geom_rbound[g2] + margin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// plane : bounding sphere filter
|
||||
if (m->geom_type[g1]==mjGEOM_PLANE && m->geom_rbound[g2]>0
|
||||
&& plane_geom(m, d, g1, g2) > margin+m->geom_rbound[g2]) {
|
||||
return;
|
||||
}
|
||||
if (m->geom_type[g2]==mjGEOM_PLANE && m->geom_rbound[g1]>0
|
||||
&& plane_geom(m, d, g2, g1) > margin+m->geom_rbound[g1]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// call collision detector to generate contacts
|
||||
num = mjCOLLISIONFUNC[type1][type2](m, d, con, g1, g2, margin);
|
||||
|
||||
// no contacts from near-phase
|
||||
if (!num) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check number of contacts, SHOULD NOT OCCUR
|
||||
if (num>mjMAXCONPAIR) {
|
||||
mju_error("Too many contacts returned by collision function");
|
||||
}
|
||||
|
||||
// remove repeated contacts in box-box
|
||||
if (type1==mjGEOM_BOX && type2==mjGEOM_BOX) {
|
||||
// use dim field to mark: -1: bad, 0: good
|
||||
for (i=0; i<num; i++) {
|
||||
con[i].dim = 0;
|
||||
}
|
||||
|
||||
// find bad
|
||||
int j;
|
||||
for (i=0; i<num-1; i++) {
|
||||
for (j=i+1; j<num; j++) {
|
||||
if (con[i].pos[0]==con[j].pos[0] &&
|
||||
con[i].pos[1]==con[j].pos[1] &&
|
||||
con[i].pos[2]==con[j].pos[2]) {
|
||||
con[i].dim = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// consolidate good
|
||||
i = 0;
|
||||
for (j=0; j<num; j++) {
|
||||
if (con[j].dim==0) {
|
||||
// different: copy
|
||||
if (i<j) {
|
||||
con[i] = con[j];
|
||||
}
|
||||
|
||||
// advance either way
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust size
|
||||
num = i;
|
||||
}
|
||||
|
||||
// set friction, solref, solimp: dynamic
|
||||
if (ipair<0) {
|
||||
// different priority
|
||||
if (m->geom_priority[g1]!=m->geom_priority[g2]) {
|
||||
int gp = (m->geom_priority[g1]>m->geom_priority[g2] ? g1 : g2);
|
||||
|
||||
// friction
|
||||
for (i=0; i<3; i++) {
|
||||
friction[2*i] = m->geom_friction[3*gp+i];
|
||||
}
|
||||
|
||||
// reference
|
||||
mju_copy(solref, m->geom_solref+mjNREF*gp, mjNREF);
|
||||
|
||||
// impedance
|
||||
mju_copy(solimp, m->geom_solimp+mjNIMP*gp, mjNIMP);
|
||||
}
|
||||
|
||||
// same priority
|
||||
else {
|
||||
// friction: max
|
||||
for (i=0; i<3; i++) {
|
||||
friction[2*i] = mju_max(m->geom_friction[3*g1+i], m->geom_friction[3*g2+i]);
|
||||
}
|
||||
|
||||
// solver mix factor
|
||||
if (m->geom_solmix[g1]>=mjMINVAL && m->geom_solmix[g2]>=mjMINVAL) {
|
||||
mix = m->geom_solmix[g1] / (m->geom_solmix[g1] + m->geom_solmix[g2]);
|
||||
} else if (m->geom_solmix[g1]<mjMINVAL && m->geom_solmix[g2]<mjMINVAL) {
|
||||
mix = 0.5;
|
||||
} else if (m->geom_solmix[g1]<mjMINVAL) {
|
||||
mix = 0.0;
|
||||
} else {
|
||||
mix = 1.0;
|
||||
}
|
||||
|
||||
// reference standard: mix
|
||||
if (m->geom_solref[mjNREF*g1]>0 && m->geom_solref[mjNREF*g2]>0) {
|
||||
for (i=0; i<mjNREF; i++) {
|
||||
solref[i] = mix*m->geom_solref[mjNREF*g1+i] + (1-mix)*m->geom_solref[mjNREF*g2+i];
|
||||
}
|
||||
}
|
||||
|
||||
// reference direct: min
|
||||
else {
|
||||
for (i=0; i<mjNREF; i++) {
|
||||
solref[i] = mju_min(m->geom_solref[mjNREF*g1+i], m->geom_solref[mjNREF*g2+i]);
|
||||
}
|
||||
}
|
||||
|
||||
// impedance: mix
|
||||
mju_scl(solimp, m->geom_solimp+mjNIMP*g1, mix, mjNIMP);
|
||||
mju_addToScl(solimp, m->geom_solimp+mjNIMP*g2, 1-mix, mjNIMP);
|
||||
}
|
||||
|
||||
// unpack 5D friction
|
||||
friction[1] = friction[0];
|
||||
friction[3] = friction[4];
|
||||
}
|
||||
|
||||
// set friction, solref, solimp: pair
|
||||
else {
|
||||
// friction
|
||||
for (i=0; i<5; i++) {
|
||||
friction[i] = m->pair_friction[5*ipair+i];
|
||||
}
|
||||
|
||||
// reference
|
||||
mju_copy(solref, m->pair_solref+mjNREF*ipair, mjNREF);
|
||||
|
||||
// impedance
|
||||
mju_copy(solimp, m->pair_solimp+mjNIMP*ipair, mjNIMP);
|
||||
}
|
||||
|
||||
// clamp friction to mjMINMU
|
||||
for (i=0; i<5; i++) {
|
||||
friction[i] = mju_max(mjMINMU, friction[i]);
|
||||
}
|
||||
|
||||
// add contact returned by collision detector
|
||||
for (i=0; i<num; i++) {
|
||||
// set contact data
|
||||
if (condim > 6 || condim < 0) { // SHOULD NOT OCCUR
|
||||
mju_error_i("Invalid condim value: %d", i);
|
||||
}
|
||||
con[i].dim = condim;
|
||||
con[i].geom1 = g1;
|
||||
con[i].geom2 = g2;
|
||||
con[i].includemargin = margin-gap;
|
||||
mju_copy(con[i].friction, friction, 5);
|
||||
mj_assignRef(m, con[i].solref, solref);
|
||||
mj_assignImp(m, con[i].solimp, solimp);
|
||||
|
||||
// exclude in gap
|
||||
if (con[i].dist<con[i].includemargin) {
|
||||
con[i].exclude = 0;
|
||||
} else {
|
||||
con[i].exclude = 1;
|
||||
}
|
||||
|
||||
// complete frame
|
||||
mju_makeFrame(con[i].frame);
|
||||
|
||||
// clear fields that are computed later
|
||||
con[i].efc_address = -1;
|
||||
con[i].mu = 0;
|
||||
mju_zero(con[i].H, 36);
|
||||
// add to mjData, abort if too many contacts
|
||||
if (mj_addContact(m, d, con + i)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// filter contacts: 1- discard, 0- proceed
|
||||
int mj_contactFilter(int type1, int contype1, int conaffinity1, int weldbody1, int weldparent1,
|
||||
int type2, int contype2, int conaffinity2, int weldbody2, int weldparent2,
|
||||
int filterparent) {
|
||||
// compatibility check
|
||||
if (!(contype1 & conaffinity2) && !(contype2 & conaffinity1)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// same weldbody check
|
||||
if (weldbody1==weldbody2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// weldparent check
|
||||
if (filterparent && (weldbody1==weldparent2 || weldbody2==weldparent1)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// all tests passed
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_COLLISION_DRIVER_H_
|
||||
#define MUJOCO_SRC_ENGINE_ENGINE_COLLISION_DRIVER_H_
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjexport.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// collision function pointers and max contact pairs
|
||||
MJAPI extern mjfCollision mjCOLLISIONFUNC[mjNGEOMTYPES][mjNGEOMTYPES];
|
||||
|
||||
// collision detection entry point
|
||||
MJAPI void mj_collision(const mjModel* m, mjData* d);
|
||||
|
||||
// broad phase collistion detection; return list of body pairs for narrow phase
|
||||
int mj_broadphase(const mjModel* m, mjData* d, int* bodypair, int maxpair);
|
||||
|
||||
// test two geoms for collision, apply filters, add to contact list
|
||||
// flg_user disables filters and uses usermargin
|
||||
void mj_collideGeoms(const mjModel* m, mjData* d,
|
||||
int g1, int g2, int flg_user, mjtNum usermargin);
|
||||
|
||||
// number of possible collisions based on fitlers and geom types
|
||||
int mj_contactFilter(int type1, int contype1, int conaffinity1, int weldbody1, int weldparent1,
|
||||
int type2, int contype2, int conaffinity2, int weldbody2, int weldparent2,
|
||||
int filterparent);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_COLLISION_DRIVER_H_
|
||||
@@ -0,0 +1,460 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "engine/engine_collision_primitive.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include "engine/engine_util_blas.h"
|
||||
#include "engine/engine_util_spatial.h"
|
||||
|
||||
|
||||
//--------------------------- plane collisions -----------------------------------------------------
|
||||
|
||||
// plane : sphere (actual implementation, can be called with modified parameters)
|
||||
static int _PlaneSphere(mjContact* con, mjtNum margin,
|
||||
mjtNum* pos1, mjtNum* mat1, mjtNum* size1,
|
||||
mjtNum* pos2, mjtNum* mat2, mjtNum* size2) {
|
||||
mjtNum tmp[3];
|
||||
mjtNum cdist;
|
||||
|
||||
// set normal
|
||||
con[0].frame[0] = mat1[2];
|
||||
con[0].frame[1] = mat1[5];
|
||||
con[0].frame[2] = mat1[8];
|
||||
|
||||
// compute distance, return if too large
|
||||
mju_sub3(tmp, pos2, pos1);
|
||||
cdist = mju_dot3(tmp, con[0].frame);
|
||||
if (cdist > margin + size2[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// depth and position
|
||||
con[0].dist = cdist - size2[0];
|
||||
mju_scl3(tmp, con[0].frame, -con[0].dist/2 - size2[0]);
|
||||
mju_add3(con[0].pos, pos2, tmp);
|
||||
|
||||
mju_zero3(con[0].frame+3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// plane : sphere
|
||||
int mjc_PlaneSphere(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
return _PlaneSphere(con, margin, pos1, mat1, size1, pos2, mat2, size2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// plane : capsule
|
||||
int mjc_PlaneCapsule(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
mjtNum pos[3], axis[3], segment[3];
|
||||
int n1, n2;
|
||||
|
||||
// get capsule axis, segment = scaled axis
|
||||
axis[0] = mat2[2];
|
||||
axis[1] = mat2[5];
|
||||
axis[2] = mat2[8];
|
||||
mju_scl3(segment, axis, size2[1]);
|
||||
|
||||
// get point 1, do sphere-plane test
|
||||
mju_add3(pos, pos2, segment);
|
||||
n1 = _PlaneSphere(con, margin, pos1, mat1, size1, pos, mat2, size2);
|
||||
|
||||
// get point 2, do sphere-plane test
|
||||
mju_sub3(pos, pos2, segment);
|
||||
n2 = _PlaneSphere(con+n1, margin, pos1, mat1, size1, pos, mat2, size2);
|
||||
|
||||
// align contact frames with capsule axis
|
||||
if (n1) {
|
||||
mju_copy3(con->frame+3, axis);
|
||||
}
|
||||
if (n2) {
|
||||
mju_copy3((con+n1)->frame+3, axis);
|
||||
}
|
||||
|
||||
return n1+n2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// plane : cylinder
|
||||
int mjc_PlaneCylinder(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
mjtNum normal[3] = {mat1[2], mat1[5], mat1[8]};
|
||||
mjtNum axis[3] = {mat2[2], mat2[5], mat2[8]};
|
||||
mjtNum vec[3], vec1[3];
|
||||
mjtNum len, scl, dist0, prjaxis, prjvec, prjvec1;
|
||||
int cnt = 0;
|
||||
|
||||
// project, make sure axis points towards plane
|
||||
prjaxis = mju_dot3(normal, axis);
|
||||
if (prjaxis > 0) {
|
||||
mju_scl3(axis, axis, -1);
|
||||
prjaxis = -prjaxis;
|
||||
}
|
||||
|
||||
// compute normal distance to cylinder center
|
||||
mju_sub3(vec, pos2, pos1);
|
||||
dist0 = mju_dot3(vec, normal);
|
||||
|
||||
// remove component of -normal along axis, compute length
|
||||
mju_scl3(vec, axis, prjaxis);
|
||||
mju_subFrom3(vec, normal);
|
||||
len = mju_norm3(vec);
|
||||
|
||||
// general configuration: normalize vector, scale by radius
|
||||
if (len >= mjMINVAL) {
|
||||
scl = size2[0]/len;
|
||||
vec[0] *= scl;
|
||||
vec[1] *= scl;
|
||||
vec[2] *= scl;
|
||||
}
|
||||
|
||||
// disk parallel to plane: pick x-axis of cylinder, scale by radius
|
||||
else {
|
||||
vec[0] = mat2[0]*size2[0];
|
||||
vec[1] = mat2[3]*size2[0];
|
||||
vec[2] = mat2[6]*size2[0];
|
||||
}
|
||||
|
||||
// project vector on normal
|
||||
prjvec = mju_dot3(vec, normal);
|
||||
|
||||
// scale axis by half-length
|
||||
mju_scl3(axis, axis, size2[1]);
|
||||
prjaxis *= size2[1];
|
||||
|
||||
// check first point, construct contact
|
||||
if (dist0 + prjaxis + prjvec <= margin) {
|
||||
con[cnt].dist = dist0 + prjaxis + prjvec;
|
||||
mju_add3(con[cnt].pos, pos2, vec);
|
||||
mju_addTo3(con[cnt].pos, axis);
|
||||
mju_addToScl3(con[cnt].pos, normal, -con[cnt].dist*0.5);
|
||||
mju_copy3(con[cnt].frame, normal);
|
||||
mju_zero3(con[cnt].frame+3);
|
||||
cnt++;
|
||||
} else {
|
||||
return 0; // nearest point is above margin: no contacts
|
||||
}
|
||||
|
||||
// check second point, construct contact
|
||||
if (dist0 - prjaxis + prjvec <= margin) {
|
||||
con[cnt].dist = dist0 - prjaxis + prjvec;
|
||||
mju_add3(con[cnt].pos, pos2, vec);
|
||||
mju_subFrom3(con[cnt].pos, axis);
|
||||
mju_addToScl3(con[cnt].pos, normal, -con[cnt].dist*0.5);
|
||||
mju_copy3(con[cnt].frame, normal);
|
||||
mju_zero3(con[cnt].frame+3);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
// try to add triangle points on side closer to plane
|
||||
prjvec1 = -prjvec*0.5;
|
||||
if (dist0 + prjaxis + prjvec1 <= margin) {
|
||||
// compute sideways vector: vec1
|
||||
mju_cross(vec1, vec, axis);
|
||||
mju_normalize3(vec1);
|
||||
mju_scl3(vec1, vec1, size2[0]*mju_sqrt(3.0)/2);
|
||||
|
||||
// add point A
|
||||
con[cnt].dist = dist0 + prjaxis + prjvec1;
|
||||
mju_add3(con[cnt].pos, pos2, vec1);
|
||||
mju_addTo3(con[cnt].pos, axis);
|
||||
mju_addToScl3(con[cnt].pos, vec, -0.5);
|
||||
mju_addToScl3(con[cnt].pos, normal, -con[cnt].dist*0.5);
|
||||
mju_copy3(con[cnt].frame, normal);
|
||||
mju_zero3(con[cnt].frame+3);
|
||||
cnt++;
|
||||
|
||||
// add point B
|
||||
con[cnt].dist = dist0 + prjaxis + prjvec1;
|
||||
mju_sub3(con[cnt].pos, pos2, vec1);
|
||||
mju_addTo3(con[cnt].pos, axis);
|
||||
mju_addToScl3(con[cnt].pos, vec, -0.5);
|
||||
mju_addToScl3(con[cnt].pos, normal, -con[cnt].dist*0.5);
|
||||
mju_copy3(con[cnt].frame, normal);
|
||||
mju_zero3(con[cnt].frame+3);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// plane : box
|
||||
int mjc_PlaneBox(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
int cnt = 0;
|
||||
|
||||
// get normal, difference between centers, normal distance
|
||||
mjtNum norm[3] = {mat1[2], mat1[5], mat1[8]};
|
||||
mjtNum dif[3], vec[3], corner[3], dist, ldist;
|
||||
mju_sub3(dif, pos2, pos1);
|
||||
dist = mju_dot3(dif, norm);
|
||||
|
||||
// test all corners, pick bottom 4
|
||||
for (int i=0; i<8; i++) {
|
||||
// get corner in local coordinates
|
||||
vec[0] = (i&1 ? size2[0] : -size2[0]);
|
||||
vec[1] = (i&2 ? size2[1] : -size2[1]);
|
||||
vec[2] = (i&4 ? size2[2] : -size2[2]);
|
||||
|
||||
// get corner in global coordinates relative to box center
|
||||
mju_rotVecMat(corner, vec, mat2);
|
||||
|
||||
// compute distance to plane, skip if too far or pointing up
|
||||
ldist = mju_dot3(norm, corner);
|
||||
if (dist + ldist > margin || ldist > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// construct contact
|
||||
con[cnt].dist = dist + ldist;
|
||||
mju_copy3(con[cnt].frame, norm);
|
||||
mju_zero3(con[cnt].frame+3);
|
||||
mju_addTo3(corner, pos2);
|
||||
mju_scl3(vec, norm, -con[cnt].dist/2);
|
||||
mju_add3(con[cnt].pos, corner, vec);
|
||||
|
||||
// count; max is 4
|
||||
if (++cnt >= 4) {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------- sphere and capsule collisions ----------------------------------------
|
||||
|
||||
// sphere : sphere (actual implementation, can be called with modified parameters)
|
||||
static int _SphereSphere(mjContact* con, mjtNum margin,
|
||||
mjtNum* pos1, mjtNum* mat1, mjtNum* size1,
|
||||
mjtNum* pos2, mjtNum* mat2, mjtNum* size2) {
|
||||
mjtNum len, cdist;
|
||||
mjtNum axis1[3], axis2[3];
|
||||
|
||||
// check bounding spheres (this is called from other functions)
|
||||
cdist = mju_dist3(pos1, pos2);
|
||||
if (cdist > margin + size1[0] + size2[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// depth and normal
|
||||
con[0].dist = cdist - size1[0] - size2[0];
|
||||
mju_sub3(con[0].frame, pos2, pos1);
|
||||
len = mju_normalize3(con[0].frame);
|
||||
|
||||
// if centers are the same, norm = cross-product of z axes
|
||||
// if z axes are parallel, norm = [1;0;0]
|
||||
if (len < mjMINVAL) {
|
||||
axis1[0] = mat1[2];
|
||||
axis1[1] = mat1[5];
|
||||
axis1[2] = mat1[8];
|
||||
axis2[0] = mat2[2];
|
||||
axis2[1] = mat2[5];
|
||||
axis2[2] = mat2[8];
|
||||
mju_cross(con[0].frame, axis1, axis2);
|
||||
mju_normalize3(con[0].frame);
|
||||
}
|
||||
|
||||
// position
|
||||
mju_scl3(con[0].pos, con[0].frame, size1[0] + con[0].dist/2);
|
||||
mju_addTo3(con[0].pos, pos1);
|
||||
|
||||
mju_zero3(con[0].frame+3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sphere : sphere
|
||||
int mjc_SphereSphere(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
return _SphereSphere(con, margin, pos1, mat1, size1, pos2, mat2, size2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sphere : capsule
|
||||
int mjc_SphereCapsule(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
mjtNum x, axis[3], vec[3];
|
||||
|
||||
// get capsule axis (scaled)
|
||||
axis[0] = mat2[2] * size2[1];
|
||||
axis[1] = mat2[5] * size2[1];
|
||||
axis[2] = mat2[8] * size2[1];
|
||||
|
||||
// find projection, clip to segment
|
||||
mju_sub3(vec, pos1, pos2);
|
||||
x = mju_dot3(axis, vec) / mju_dot3(axis, axis);
|
||||
if (x > 1) {
|
||||
x = 1;
|
||||
} else if (x < -1) {
|
||||
x = -1;
|
||||
}
|
||||
|
||||
// find nearest point on segment, do sphere-sphere test
|
||||
mju_scl3(vec, axis, x);
|
||||
mju_addTo3(vec, pos2);
|
||||
return _SphereSphere(con, margin, pos1, mat1, size1, vec, mat2, size2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// capsule : capsule
|
||||
int mjc_CapsuleCapsule(const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||
mjGETINFO
|
||||
mjtNum axis1[3], axis2[3], dif[3], vec1[3], vec2[3];
|
||||
mjtNum ma, mb, mc, u, v, det, x1, x2;
|
||||
int n1, n2, n3, n4;
|
||||
|
||||
// get capsule axes (scaled) and center difference
|
||||
axis1[0] = mat1[2] * size1[1];
|
||||
axis1[1] = mat1[5] * size1[1];
|
||||
axis1[2] = mat1[8] * size1[1];
|
||||
axis2[0] = mat2[2] * size2[1];
|
||||
axis2[1] = mat2[5] * size2[1];
|
||||
axis2[2] = mat2[8] * size2[1];
|
||||
mju_sub3(dif, pos1, pos2);
|
||||
|
||||
// compute matrix coefficients and determinant
|
||||
ma = mju_dot3(axis1, axis1);
|
||||
mb = -mju_dot3(axis1, axis2);
|
||||
mc = mju_dot3(axis2, axis2);
|
||||
u = -mju_dot3(axis1, dif);
|
||||
v = mju_dot3(axis2, dif);
|
||||
det = ma*mc - mb*mb;
|
||||
|
||||
// general configuration (non-parallel axes)
|
||||
if (fabs(det) >= mjMINVAL) {
|
||||
// find projections, clip to segments
|
||||
x1 = (mc*u - mb*v) / det;
|
||||
x2 = (ma*v - mb*u) / det;
|
||||
|
||||
if (x1 > 1) {
|
||||
x1 = 1;
|
||||
x2 = (v-mb)/mc;
|
||||
} else if (x1 < -1) {
|
||||
x1 = -1;
|
||||
x2 = (v+mb)/mc;
|
||||
}
|
||||
if (x2 > 1) {
|
||||
x2 = 1;
|
||||
x1 = (u-mb)/ma;
|
||||
if (x1 > 1) {
|
||||
x1 = 1;
|
||||
} else if (x1 < -1) {
|
||||
x1 = -1;
|
||||
}
|
||||
} else if (x2 < -1) {
|
||||
x2 = -1;
|
||||
x1 = (u+mb)/ma;
|
||||
if (x1 > 1) {
|
||||
x1 = 1;
|
||||
} else if (x1 < -1) {
|
||||
x1 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// find nearest points, do sphere-sphere test
|
||||
mju_scl3(vec1, axis1, x1);
|
||||
mju_addTo3(vec1, pos1);
|
||||
mju_scl3(vec2, axis2, x2);
|
||||
mju_addTo3(vec2, pos2);
|
||||
|
||||
return _SphereSphere(con, margin, vec1, mat1, size1, vec2, mat2, size2);
|
||||
}
|
||||
|
||||
// parallel axes
|
||||
else {
|
||||
// x1 = 1
|
||||
mju_add3(vec1, pos1, axis1);
|
||||
x2 = (v - mb) / mc;
|
||||
if (x2 > 1) {
|
||||
x2 = 1;
|
||||
} else if (x2 < -1) {
|
||||
x2 = -1;
|
||||
}
|
||||
mju_scl3(vec2, axis2, x2);
|
||||
mju_addTo3(vec2, pos2);
|
||||
n1 = _SphereSphere(con, margin, vec1, mat1, size1, vec2, mat2, size2);
|
||||
|
||||
// x1 = -1
|
||||
mju_sub3(vec1, pos1, axis1);
|
||||
x2 = (v + mb) / mc;
|
||||
if (x2 > 1) {
|
||||
x2 = 1;
|
||||
} else if (x2 < -1) {
|
||||
x2 = -1;
|
||||
}
|
||||
mju_scl3(vec2, axis2, x2);
|
||||
mju_addTo3(vec2, pos2);
|
||||
n2 = _SphereSphere(con+n1, margin, vec1, mat1, size1, vec2, mat2, size2);
|
||||
|
||||
// return if two contacts already found
|
||||
if (n1+n2>=2) {
|
||||
return n1+n2;
|
||||
}
|
||||
|
||||
// x2 = 1
|
||||
mju_add3(vec2, pos2, axis2);
|
||||
x1 = (u - mb) / ma;
|
||||
if (x1 > 1) {
|
||||
x1 = 1;
|
||||
} else if (x1 < -1) {
|
||||
x1 = -1;
|
||||
}
|
||||
mju_scl3(vec1, axis1, x1);
|
||||
mju_addTo3(vec1, pos1);
|
||||
n3 = _SphereSphere(con+n1+n2, margin, vec1, mat1, size1, vec2, mat2, size2);
|
||||
|
||||
// return if two contacts already found
|
||||
if (n1+n2+n3>=2) {
|
||||
return n1+n2+n3;
|
||||
}
|
||||
|
||||
// x2 = -1
|
||||
mju_sub3(vec2, pos2, axis2);
|
||||
x1 = (u + mb) / ma;
|
||||
if (x1 > 1) {
|
||||
x1 = 1;
|
||||
} else if (x1 < -1) {
|
||||
x1 = -1;
|
||||
}
|
||||
mju_scl3(vec1, axis1, x1);
|
||||
mju_addTo3(vec1, pos1);
|
||||
n4 = _SphereSphere(con+n1+n2+n3, margin, vec1, mat1, size1, vec2, mat2, size2);
|
||||
|
||||
return n1+n2+n3+n4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_COLLISION_PRIMITIVE_H_
|
||||
#define MUJOCO_SRC_ENGINE_ENGINE_COLLISION_PRIMITIVE_H_
|
||||
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
|
||||
// define and extract geom info
|
||||
#define mjGETINFO \
|
||||
mjtNum* pos1 = d->geom_xpos + 3*g1; \
|
||||
mjtNum* mat1 = d->geom_xmat + 9*g1; \
|
||||
mjtNum* size1= m->geom_size + 3*g1; \
|
||||
mjtNum* pos2 = d->geom_xpos + 3*g2; \
|
||||
mjtNum* mat2 = d->geom_xmat + 9*g2; \
|
||||
mjtNum* size2= m->geom_size + 3*g2; \
|
||||
(void) size1; (void) size2;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// plane collisions
|
||||
int mjc_PlaneSphere (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_PlaneCapsule (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_PlaneCylinder (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_PlaneBox (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
|
||||
// sphere and capsule collisions
|
||||
int mjc_SphereSphere (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_SphereCapsule (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_CapsuleCapsule (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
|
||||
// box collisions: from boxcollisions.c
|
||||
int mjc_CapsuleBox (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_SphereBox (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
int mjc_BoxBox (const mjModel* m, const mjData* d,
|
||||
mjContact* con, int g1, int g2, mjtNum margin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_COLLISION_PRIMITIVE_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user