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,
|
We intend for MuJoCo to be a true community-driven project and look forward to
|
||||||
however the full source code for the Python bindings and the Unity plugin are
|
accepting your contributions!
|
||||||
already released. You are welcome to send us pull requests to improve any part
|
|
||||||
of this repository.
|
|
||||||
|
|
||||||
## 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
|
Contributions to this project must be accompanied by a Contributor License
|
||||||
Agreement. You (or your employer) retain the copyright to your contribution,
|
Agreement (CLA). You (or your employer) retain the copyright to your
|
||||||
this simply gives us permission to use and redistribute your contributions as
|
contribution; this simply gives us permission to use and redistribute your
|
||||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
contributions as part of the project. Head over to
|
||||||
your current agreements on file or to sign a new one.
|
<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
|
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
|
(even if it was for a different project), you probably don't need to do it
|
||||||
again.
|
again.
|
||||||
|
|
||||||
## Code reviews
|
## Contributing
|
||||||
|
|
||||||
All submissions require review. Please use GitHub pull requests for this
|
### Reporting bugs
|
||||||
purpose. Consult
|
|
||||||
|
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
|
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||||
information on pull requests.
|
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
|
areas which demand fast and accurate simulation of articulated structures
|
||||||
interacting with their environment.
|
interacting with their environment.
|
||||||
|
|
||||||
DeepMind has acquired MuJoCo, and we are currently making preparations to open
|
This repository is maintained by DeepMind, please see our [acquisition] and
|
||||||
source the codebase. In the meantime, MuJoCo is available for download as a free
|
[open sourcing] announcements.
|
||||||
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).
|
|
||||||
|
|
||||||
|
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
|
## Documentation
|
||||||
|
|
||||||
MuJoco's current documentation is available at [mujoco.org/book], which is
|
MuJoCo's documentation is available at [mujoco.readthedocs.io], which serves
|
||||||
serving Sphinx-based webpages derived from the ReStructuredText
|
webpages derived from the [documentation source files].
|
||||||
[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
|
## Citation
|
||||||
@@ -85,19 +58,23 @@ If you use MuJoCo for published research, please cite:
|
|||||||
|
|
||||||
```
|
```
|
||||||
@inproceedings{todorov2012mujoco,
|
@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},
|
author={Todorov, Emanuel and Erez, Tom and Tassa, Yuval},
|
||||||
booktitle={2012 IEEE/RSJ International Conference on Intelligent Robots and Systems},
|
booktitle={2012 IEEE/RSJ International Conference on Intelligent Robots and Systems},
|
||||||
pages={5026--5033},
|
pages={5026--5033},
|
||||||
year={2012},
|
year={2012},
|
||||||
organization={IEEE}
|
organization={IEEE},
|
||||||
|
doi={10.1109/IROS.2012.6386109}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## License and Disclaimer
|
## 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
|
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)
|
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.
|
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
|
[GitHub Issues]: https://github.com/deepmind/mujoco/issues
|
||||||
[documentation source files]: https://github.com/deepmind/mujoco/tree/main/doc
|
[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:
|
# Arguments:
|
||||||
# - ``USE_SYSTEM_PACKAGE`` one-value argument on whether to search for the
|
# - ``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
|
# package in the system (ON) or whether to fetch the library using
|
||||||
# repository (OFF).
|
# FetchContent from the specified Git repository (OFF). Note that
|
||||||
|
# FetchContent variables will override this behaviour.
|
||||||
# - ``PACKAGE_NAME`` name of the system-package. Ignored if
|
# - ``PACKAGE_NAME`` name of the system-package. Ignored if
|
||||||
# ``USE_SYSTEM_PACKAGE`` is ``OFF``.
|
# ``USE_SYSTEM_PACKAGE`` is ``OFF``.
|
||||||
# - ``LIBRARY_NAME`` name of the library. Ignored if
|
# - ``LIBRARY_NAME`` name of the library. Ignored if
|
||||||
@@ -41,9 +42,19 @@
|
|||||||
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
||||||
# - ``GIT_TAG`` tag reference when fetching the library from the git
|
# - ``GIT_TAG`` tag reference when fetching the library from the git
|
||||||
# repository. Ignored if ``USE_SYSTEM_PACKAGE`` is ``ON``.
|
# 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
|
# - ``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
|
# not currently defined, this macro will attempt to either find or fetch the
|
||||||
# package.
|
# 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)
|
if(COMMAND FindOrFetch)
|
||||||
return()
|
return()
|
||||||
@@ -76,10 +87,14 @@ macro(FindOrFetch)
|
|||||||
if(NOT _ARGS_TARGETS)
|
if(NOT _ARGS_TARGETS)
|
||||||
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
|
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(targets_found TRUE)
|
set(targets_found TRUE)
|
||||||
|
message(CHECK_START
|
||||||
|
"mujoco::FindOrFetch: checking for targets in package `${_ARGS_PACKAGE_NAME}`"
|
||||||
|
)
|
||||||
foreach(target ${_ARGS_TARGETS})
|
foreach(target ${_ARGS_TARGETS})
|
||||||
if(NOT TARGET ${target})
|
if(NOT TARGET ${target})
|
||||||
message(STATUS "mujoco::FindOrFetch: target `${target}` not defined.")
|
message(CHECK_FAIL "target `${target}` not defined.")
|
||||||
set(targets_found FALSE)
|
set(targets_found FALSE)
|
||||||
break()
|
break()
|
||||||
endif()
|
endif()
|
||||||
@@ -88,16 +103,14 @@ macro(FindOrFetch)
|
|||||||
# If targets are not found, use `find_package` or `FetchContent...` to get it.
|
# If targets are not found, use `find_package` or `FetchContent...` to get it.
|
||||||
if(NOT targets_found)
|
if(NOT targets_found)
|
||||||
if(${_ARGS_USE_SYSTEM_PACKAGE})
|
if(${_ARGS_USE_SYSTEM_PACKAGE})
|
||||||
message(
|
message(CHECK_START
|
||||||
STATUS
|
"mujoco::FindOrFetch: finding `${_ARGS_PACKAGE_NAME}` in system packages..."
|
||||||
"mujoco::FindOrFetch: Attempting to find `${_ARGS_PACKAGE_NAME}` in system packages..."
|
|
||||||
)
|
)
|
||||||
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
|
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
|
||||||
message(STATUS "mujoco::FindOrFetch: Found `${_ARGS_PACKAGE_NAME}` in system packages.")
|
message(CHECK_PASS "found")
|
||||||
else()
|
else()
|
||||||
message(
|
message(CHECK_START
|
||||||
STATUS
|
"mujoco::FindOrFetch: Using FetchContent to retrieve `${_ARGS_LIBRARY_NAME}`"
|
||||||
"mujoco::FindOrFetch: Attempting to fetch `${_ARGS_LIBRARY_NAME}` from `${_ARGS_GIT_REPO}`..."
|
|
||||||
)
|
)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
${_ARGS_LIBRARY_NAME}
|
${_ARGS_LIBRARY_NAME}
|
||||||
@@ -118,11 +131,9 @@ macro(FindOrFetch)
|
|||||||
else()
|
else()
|
||||||
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
|
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
|
||||||
endif()
|
endif()
|
||||||
message(
|
message(CHECK_PASS "Done")
|
||||||
STATUS "mujoco::FindOrFetch: Fetched `${_ARGS_LIBRARY_NAME}` from `${_ARGS_GIT_REPO}`."
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "mujoco::FindOrFetch: `${_ARGS_PACKAGE_NAME}` targets found.")
|
message(CHECK_PASS "found")
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
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;
|
typedef float mjtNum;
|
||||||
#endif
|
#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
|
| 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
|
``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;
|
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.
|
| Byte type used to represent boolean variables.
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ mjtDisableBit
|
|||||||
mjNDISABLE = 12 // number of disable flags
|
mjNDISABLE = 12 // number of disable flags
|
||||||
} mjtDisableBit;
|
} 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`.
|
| 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
|
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
|
mjNENABLE = 5 // number of enable flags
|
||||||
} mjtEnableBit;
|
} 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`.
|
| 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
|
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)
|
mjJNT_HINGE // rotation angle (rad) around body-fixed axis (1)
|
||||||
} mjtJoint;
|
} 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
|
| 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
|
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
|
mjGEOM_NONE = 1001 // missing geom type
|
||||||
} mjtGeom;
|
} 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
|
| 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
|
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
|
mjCAMLIGHT_TARGETBODYCOM // pos fixed in body, rot tracks target subtree com
|
||||||
} mjtCamLight;
|
} 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
|
| 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``.
|
values are used in ``m->cam_mode`` and ``m->light_mode``.
|
||||||
@@ -217,7 +217,7 @@ mjtTexture
|
|||||||
mjTEXTURE_SKYBOX // cube texture used as skybox
|
mjTEXTURE_SKYBOX // cube texture used as skybox
|
||||||
} mjtTexture;
|
} 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``.
|
| 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
|
mjINT_RK4 // 4th-order Runge Kutta
|
||||||
} mjtIntegrator;
|
} 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``.
|
| Numerical integrator types. These values are used in ``m->opt.integrator``.
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ mjtCollision
|
|||||||
mjCOL_DYNAMIC // test dynamic pairs only
|
mjCOL_DYNAMIC // test dynamic pairs only
|
||||||
} mjtCollision;
|
} 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
|
| Collision modes specifying how candidate geom pairs are generated for near-phase collision checking. These values are
|
||||||
used in ``m->opt.collision``.
|
used in ``m->opt.collision``.
|
||||||
@@ -270,7 +270,7 @@ mjtCone
|
|||||||
mjCONE_ELLIPTIC // elliptic
|
mjCONE_ELLIPTIC // elliptic
|
||||||
} mjtCone;
|
} 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``.
|
| 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
|
mjJAC_AUTO // dense if nv<=60, sparse otherwise
|
||||||
} mjtJacobian;
|
} 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``.
|
| Available Jacobian types. These values are used in ``m->opt.jacobian``.
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ mjtSolver
|
|||||||
mjSOL_NEWTON // Newton (primal)
|
mjSOL_NEWTON // Newton (primal)
|
||||||
} mjtSolver;
|
} 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``.
|
| 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
|
mjEQ_DISTANCE // fix the contact distance betweent two geoms
|
||||||
} mjtEq;
|
} 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``.
|
| Equality constraint types. These values are used in ``m->eq_type``.
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ mjtWrap
|
|||||||
mjWRAP_CYLINDER // wrap around (infinite) cylinder
|
mjWRAP_CYLINDER // wrap around (infinite) cylinder
|
||||||
} mjtWrap;
|
} 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``.
|
| Tendon wrapping object types. These values are used in ``m->wrap_type``.
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ mjtTrn
|
|||||||
mjTRN_UNDEFINED = 1000 // undefined transmission type
|
mjTRN_UNDEFINED = 1000 // undefined transmission type
|
||||||
} mjtTrn;
|
} 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``.
|
| Actuator transmission types. These values are used in ``m->actuator_trntype``.
|
||||||
|
|
||||||
@@ -389,7 +389,7 @@ mjtDyn
|
|||||||
mjDYN_USER // user-defined dynamics type
|
mjDYN_USER // user-defined dynamics type
|
||||||
} mjtDyn;
|
} 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``.
|
| Actuator dynamics types. These values are used in ``m->actuator_dyntype``.
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ mjtGain
|
|||||||
mjGAIN_USER // user-defined gain type
|
mjGAIN_USER // user-defined gain type
|
||||||
} mjtGain;
|
} 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``.
|
| Actuator gain types. These values are used in ``m->actuator_gaintype``.
|
||||||
|
|
||||||
@@ -426,7 +426,7 @@ mjtBias
|
|||||||
mjBIAS_USER // user-defined bias type
|
mjBIAS_USER // user-defined bias type
|
||||||
} mjtBias;
|
} 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``.
|
| Actuator bias types. These values are used in ``m->actuator_biastype``.
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ mjtObj
|
|||||||
mjOBJ_KEY // keyframe
|
mjOBJ_KEY // keyframe
|
||||||
} mjtObj;
|
} 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
|
| 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.
|
:ref:`mj_id2name` to convert between object names and integer ids.
|
||||||
@@ -489,7 +489,7 @@ mjtConstraint
|
|||||||
mjCNSTR_CONTACT_ELLIPTIC // frictional contact, elliptic friction cone
|
mjCNSTR_CONTACT_ELLIPTIC // frictional contact, elliptic friction cone
|
||||||
} mjtConstraint;
|
} 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
|
| 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.
|
of active constraints is constructed at each simulation time step.
|
||||||
@@ -510,7 +510,7 @@ mjtConstraintState
|
|||||||
mjCNSTRSTATE_CONE // squared distance to cone cost (elliptic contact)
|
mjCNSTRSTATE_CONE // squared distance to cone cost (elliptic contact)
|
||||||
} mjtConstraintState;
|
} 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.
|
| 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
|
mjSENS_USER // sensor data provided by mjcb_sensor callback
|
||||||
} mjtSensor;
|
} 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``.
|
| Sensor types. These values are used in ``m->sensor_type``.
|
||||||
|
|
||||||
@@ -593,7 +593,7 @@ mjtStage
|
|||||||
mjSTAGE_ACC // acceleration/force-dependent computations
|
mjSTAGE_ACC // acceleration/force-dependent computations
|
||||||
} mjtStage;
|
} 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
|
| These are the compute stages for the skipstage parameters of :ref:`mj_forwardSkip` and
|
||||||
:ref:`mj_inverseSkip`.
|
:ref:`mj_inverseSkip`.
|
||||||
@@ -613,7 +613,7 @@ mjtDataType
|
|||||||
mjDATATYPE_QUATERNION // unit quaternion
|
mjDATATYPE_QUATERNION // unit quaternion
|
||||||
} mjtDataType;
|
} 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``.
|
| These are the possible sensor data types, used in ``mjData.sensor_datatype``.
|
||||||
|
|
||||||
@@ -638,7 +638,7 @@ mjtWarning
|
|||||||
mjNWARNING // number of warnings
|
mjNWARNING // number of warnings
|
||||||
} mjtWarning;
|
} 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
|
| Warning types. The number of warning types is given by ``mjNWARNING`` which is also the length of the array
|
||||||
``mjData.warning``.
|
``mjData.warning``.
|
||||||
@@ -674,7 +674,7 @@ mjtTimer
|
|||||||
mjNTIMER // number of timers
|
mjNTIMER // number of timers
|
||||||
} mjtTimer;
|
} 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
|
| 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.
|
``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
|
mjCAT_ALL = 7 // select all categories
|
||||||
} mjtCatBit;
|
} 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
|
| 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.
|
:ref:`mjr_render` to specify which categories should be rendered.
|
||||||
@@ -717,7 +717,7 @@ mjtMouse
|
|||||||
mjMOUSE_SELECT // selection
|
mjMOUSE_SELECT // selection
|
||||||
} mjtMouse;
|
} 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
|
| 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``.
|
and translate them into these actions, as illustrated in ``simulate.cc``.
|
||||||
@@ -735,7 +735,7 @@ mjtPertBit
|
|||||||
mjPERT_ROTATE = 2 // rotation
|
mjPERT_ROTATE = 2 // rotation
|
||||||
} mjtPertBit;
|
} 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,
|
| 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
|
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
|
mjCAMERA_USER // user is responsible for setting OpenGL camera
|
||||||
} mjtCamera;
|
} 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``.
|
| These are the possible camera types, used in ``mjvCamera.type``.
|
||||||
|
|
||||||
@@ -787,7 +787,7 @@ mjtLabel
|
|||||||
mjNLABEL // number of label types
|
mjNLABEL // number of label types
|
||||||
} mjtLabel;
|
} 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``.
|
| 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
|
mjNFRAME // number of visualization frames
|
||||||
} mjtFrame;
|
} 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``.
|
| 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
|
mjNVISFLAG // number of visualization flags
|
||||||
} mjtVisFlag;
|
} 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
|
| These are indices in the array ``mjvOption.flags``, whose elements enable/disable the visualization of the
|
||||||
corresponding model or decoration element.
|
corresponding model or decoration element.
|
||||||
@@ -877,7 +877,7 @@ mjtRndFlag
|
|||||||
mjNRNDFLAG // number of rendering flags
|
mjNRNDFLAG // number of rendering flags
|
||||||
} mjtRndFlag;
|
} 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.
|
| 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
|
mjSTEREO_SIDEBYSIDE // side-by-side
|
||||||
} mjtStereo;
|
} 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``.
|
| These are the possible stereo rendering types. They are used in ``mjvScene.stereo``.
|
||||||
|
|
||||||
@@ -914,7 +914,7 @@ mjtGridPos
|
|||||||
mjGRID_BOTTOMRIGHT // bottom right
|
mjGRID_BOTTOMRIGHT // bottom right
|
||||||
} mjtGridPos;
|
} 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
|
| These are the possible grid positions for text overlays. They are used as an argument to the function
|
||||||
:ref:`mjr_overlay`.
|
:ref:`mjr_overlay`.
|
||||||
@@ -932,7 +932,7 @@ mjtFramebuffer
|
|||||||
mjFB_OFFSCREEN // offscreen buffer
|
mjFB_OFFSCREEN // offscreen buffer
|
||||||
} mjtFramebuffer;
|
} 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`.
|
| 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
|
mjFONTSCALE_300 = 300 // 300% scale
|
||||||
} mjtFontScale;
|
} 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
|
| These are the possible font sizes. The fonts are predefined bitmaps stored in the dynamic library at three different
|
||||||
sizes.
|
sizes.
|
||||||
@@ -972,7 +972,7 @@ mjtFont
|
|||||||
mjFONT_BIG // big font (for user alerts)
|
mjFONT_BIG // big font (for user alerts)
|
||||||
} mjtFont;
|
} 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.
|
| These are the possible font types.
|
||||||
|
|
||||||
@@ -991,7 +991,7 @@ mjtButton
|
|||||||
mjBUTTON_MIDDLE // middle button
|
mjBUTTON_MIDDLE // middle button
|
||||||
} mjtButton;
|
} 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.
|
| Mouse button IDs used in the UI framework.
|
||||||
|
|
||||||
@@ -1013,7 +1013,7 @@ mjtEvent
|
|||||||
mjEVENT_RESIZE // resize
|
mjEVENT_RESIZE // resize
|
||||||
} mjtEvent;
|
} 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.
|
| Event types used in the UI framework.
|
||||||
|
|
||||||
@@ -1046,7 +1046,7 @@ mjtItem
|
|||||||
mjNITEM // number of item types
|
mjNITEM // number of item types
|
||||||
} mjtItem;
|
} 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.
|
| Item types used in the UI framework.
|
||||||
|
|
||||||
@@ -1055,8 +1055,8 @@ mjtItem
|
|||||||
Function types
|
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
|
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/mjui.h>`_. The actual callback functions are documented later.
|
`mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_. The actual callback functions are documented later.
|
||||||
|
|
||||||
.. _mjfGeneric:
|
.. _mjfGeneric:
|
||||||
|
|
||||||
@@ -1163,7 +1163,7 @@ mjVFS
|
|||||||
};
|
};
|
||||||
typedef struct _mjVFS 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
|
| This is the data structure with the virtual file system. It can only be constructed programmatically, and does not
|
||||||
have an analog in MJCF.
|
have an analog in MJCF.
|
||||||
@@ -1213,7 +1213,7 @@ mjOption
|
|||||||
};
|
};
|
||||||
typedef struct _mjOption 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
|
| 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.
|
:ref:`option <option>`. One instance of it is embedded in mjModel.
|
||||||
@@ -1319,7 +1319,7 @@ mjVisual
|
|||||||
};
|
};
|
||||||
typedef struct _mjVisual 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
|
| 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.
|
:ref:`visual <visual>`. One instance of it is embedded in mjModel.
|
||||||
@@ -1341,7 +1341,7 @@ mjStatistic
|
|||||||
};
|
};
|
||||||
typedef struct _mjStatistic 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
|
| 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.
|
MJCF element :ref:`statistic <statistic>`. One instance of it is embedded in mjModel.
|
||||||
@@ -1751,7 +1751,7 @@ mjModel
|
|||||||
};
|
};
|
||||||
typedef struct _mjModel 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.
|
| 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;
|
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
|
| 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
|
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;
|
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
|
| 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.
|
mjWarningStat data structures, one for each warning type.
|
||||||
@@ -1831,7 +1831,7 @@ mjTimerStat
|
|||||||
};
|
};
|
||||||
typedef struct _mjTimerStat 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
|
| 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.
|
mjTimerStat data structures, one for each timer type.
|
||||||
@@ -1855,7 +1855,7 @@ mjSolverStat
|
|||||||
};
|
};
|
||||||
typedef struct _mjSolverStat 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
|
| 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
|
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)
|
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||||
|
|
||||||
// computed by mj_fwdAcceleration
|
// computed by mj_fwdAcceleration
|
||||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
|
||||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
mjtNum* qacc_smooth; // unconstrained acceleration (nv x 1)
|
||||||
|
|
||||||
// computed by mj_fwdConstraint/mj_inverse
|
// 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)
|
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||||
@@ -2062,7 +2062,7 @@ mjData
|
|||||||
};
|
};
|
||||||
typedef struct _mjData 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
|
| 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.
|
modifiable inputs and write their outputs.
|
||||||
@@ -2086,7 +2086,7 @@ mjvPerturb
|
|||||||
};
|
};
|
||||||
typedef struct _mjvPerturb 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.
|
| This is the data structure holding information about mouse perturbations.
|
||||||
|
|
||||||
@@ -2112,7 +2112,7 @@ mjvCamera
|
|||||||
};
|
};
|
||||||
typedef struct _mjvCamera 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.
|
| This is the data structure describing one abstract camera.
|
||||||
|
|
||||||
@@ -2139,7 +2139,7 @@ mjvGLCamera
|
|||||||
};
|
};
|
||||||
typedef struct _mjvGLCamera 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.
|
| This is the data structure describing one OpenGL camera.
|
||||||
|
|
||||||
@@ -2182,7 +2182,7 @@ mjvGeom
|
|||||||
};
|
};
|
||||||
typedef struct _mjvGeom 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
|
| 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.
|
decoration element constructed by the visualizer.
|
||||||
@@ -2210,7 +2210,7 @@ mjvLight
|
|||||||
};
|
};
|
||||||
typedef struct _mjvLight 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.
|
| This is the data structure describing one OpenGL light.
|
||||||
|
|
||||||
@@ -2234,7 +2234,7 @@ mjvOption
|
|||||||
};
|
};
|
||||||
typedef struct _mjvOption 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.
|
| This structure contains options that enable and disable the visualization of various elements.
|
||||||
|
|
||||||
@@ -2280,7 +2280,7 @@ mjvScene
|
|||||||
};
|
};
|
||||||
typedef struct _mjvScene 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.
|
| This structure contains everything needed to render the 3D scene in OpenGL.
|
||||||
|
|
||||||
@@ -2334,7 +2334,7 @@ mjvFigure
|
|||||||
};
|
};
|
||||||
typedef struct _mjvFigure 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
|
| 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
|
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;
|
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.
|
| This structure specifies a rectangle.
|
||||||
|
|
||||||
@@ -2451,7 +2451,7 @@ mjrContext
|
|||||||
};
|
};
|
||||||
typedef struct _mjrContext 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.
|
| 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;
|
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.
|
| This structure contains the keyboard and mouse state used by the UI framework.
|
||||||
|
|
||||||
@@ -2529,7 +2529,7 @@ mjuiThemeSpacing
|
|||||||
};
|
};
|
||||||
typedef struct _mjuiThemeSpacing 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.
|
| This structure defines the spacing of UI items in the theme.
|
||||||
|
|
||||||
@@ -2566,7 +2566,7 @@ mjuiThemeColor
|
|||||||
};
|
};
|
||||||
typedef struct _mjuiThemeColor 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.
|
| This structure defines the colors of UI items in the theme.
|
||||||
|
|
||||||
@@ -2624,7 +2624,7 @@ mjuiItem
|
|||||||
};
|
};
|
||||||
typedef struct _mjuiItem 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.
|
| This structure defines one UI item.
|
||||||
|
|
||||||
@@ -2651,7 +2651,7 @@ mjuiSection
|
|||||||
};
|
};
|
||||||
typedef struct _mjuiSection 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.
|
| This structure defines one section of the UI.
|
||||||
|
|
||||||
@@ -2698,7 +2698,7 @@ mjUI
|
|||||||
};
|
};
|
||||||
typedef struct _mjUI 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.
|
| This structure defines the entire UI.
|
||||||
|
|
||||||
@@ -2719,7 +2719,7 @@ mjuiDef
|
|||||||
};
|
};
|
||||||
typedef struct _mjuiDef 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.
|
| 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
|
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
|
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
|
for scripting languages, where dynamic structures matching the MuJoCo data structures need to be constructed
|
||||||
programmatically.
|
programmatically.
|
||||||
|
|
||||||
@@ -3231,7 +3231,7 @@ Numeric constants
|
|||||||
API functions
|
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,
|
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,
|
``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
|
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);
|
void mj_fwdActuation(const mjModel* m, mjData* d);
|
||||||
|
|
||||||
Compute actuator force qfrc_actuation.
|
Compute actuator force qfrc_actuator.
|
||||||
|
|
||||||
.. _mj_fwdAcceleration:
|
.. _mj_fwdAcceleration:
|
||||||
|
|
||||||
@@ -3863,7 +3863,7 @@ mj_fwdAcceleration
|
|||||||
|
|
||||||
void mj_fwdAcceleration(const mjModel* m, mjData* d);
|
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:
|
.. _mj_fwdConstraint:
|
||||||
|
|
||||||
@@ -6118,7 +6118,7 @@ mju_mulQuat
|
|||||||
|
|
||||||
void mju_mulQuat(mjtNum res[4], const mjtNum quat1[4], const mjtNum quat2[4]);
|
void mju_mulQuat(mjtNum res[4], const mjtNum quat1[4], const mjtNum quat2[4]);
|
||||||
|
|
||||||
Muiltiply quaternions.
|
Multiply quaternions.
|
||||||
|
|
||||||
.. _mju_mulQuatAxis:
|
.. _mju_mulQuatAxis:
|
||||||
|
|
||||||
@@ -6129,7 +6129,7 @@ mju_mulQuatAxis
|
|||||||
|
|
||||||
void mju_mulQuatAxis(mjtNum res[4], const mjtNum quat[4], const mjtNum axis[3]);
|
void mju_mulQuatAxis(mjtNum res[4], const mjtNum quat[4], const mjtNum axis[3]);
|
||||||
|
|
||||||
Muiltiply quaternion and axis.
|
Multiply quaternion and axis.
|
||||||
|
|
||||||
.. _mju_axisAngle2Quat:
|
.. _mju_axisAngle2Quat:
|
||||||
|
|
||||||
|
|||||||
+130
-116
@@ -12,10 +12,10 @@ This chapter is the reference manual for the MJCF modeling language used in MuJo
|
|||||||
XML schema
|
XML schema
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
| The table below summarizes the XML elements and their attributes in MJCF. It is generated automatically with the
|
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.
|
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;
|
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:
|
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
|
**!** required element, can appear only once
|
||||||
@@ -24,8 +24,6 @@ XML schema
|
|||||||
**R** optional element, can appear many times recursively
|
**R** optional element, can appear many times recursively
|
||||||
====== ===================================================
|
====== ===================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
+--------------------------+----+------------------------------------------------------------------------------------+
|
+--------------------------+----+------------------------------------------------------------------------------------+
|
||||||
| :el:`mujoco` | ! | .. table:: |
|
| :el:`mujoco` | ! | .. table:: |
|
||||||
| | | :class: mjcf-attributes |
|
| | | :class: mjcf-attributes |
|
||||||
@@ -355,15 +353,17 @@ XML schema
|
|||||||
| | | :class: mjcf-attributes |
|
| | | :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:: |
|
| |_2|:el:`motor` | ? | .. table:: |
|
||||||
@@ -891,19 +891,21 @@ XML schema
|
|||||||
| | | +-------------------------+-------------------------+-------------------------+ |
|
| | | +-------------------------+-------------------------+-------------------------+ |
|
||||||
| | | | :at:`name` | :at:`class` | :at:`group` | |
|
| | | | :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:: |
|
| |_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
|
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.
|
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
|
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
|
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
|
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** (*)
|
:el-prefix:`asset/` **skin** (*)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
| Skinned meshes (or skins) were added in MuJoCo 2.0. These are deformable meshes whose vertex positions and normals 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
|
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
|
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
|
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
|
referenced from anywhere else in the model. It is a stand-alone asset that is used by renderer and not by the
|
||||||
simulator.
|
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
|
The skin has vertex positions and normals updated at runtime, and triangle faces and optional texture coordinates
|
||||||
:el:`bone` subelement. Each bone has a list of vertex indices and corresponding real-valued weights which specify how
|
which are predefined. It also has "bones" used for updating. Bones are regular MuJoCo bodies referenced with the
|
||||||
much the bone position and orientation influence the corresponding vertex. The vertex has local coordinates with
|
:el:`bone` subelement. Each bone has a list of vertex indices and corresponding real-valued weights which specify how
|
||||||
respect to every bone that influences it. The local coordinates are computed by the model compiler, given global
|
much the bone position and orientation influence the corresponding vertex. The vertex has local coordinates with
|
||||||
vertex coordinates and global bind poses for each body. The bind poses do not have to correspond to the model
|
respect to every bone that influences it. The local coordinates are computed by the model compiler, given global
|
||||||
reference configuration qpos0. Note that the vertex positions and bone bind poses provided in the skin definition are
|
vertex coordinates and global bind poses for each body. The bind poses do not have to correspond to the model
|
||||||
always global, even if the model itself is defined in local coordinates.
|
reference configuration qpos0. Note that the vertex positions and bone bind poses provided in the skin definition are
|
||||||
| At runtime the local coordinates of each vertex with respect to each bone that influences it are converted to global
|
always global, even if the model itself is defined in local coordinates.
|
||||||
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.
|
At runtime the local coordinates of each vertex with respect to each bone that influences it are converted to global
|
||||||
Finally, the skin can be inflated by applying an offset to each vertex position along its (computed) normal.
|
coordinates, and averaged in proportion to the corresponding weights to obtain a single set of 3D coordinates for each
|
||||||
| Skins are one-sided for rendering purposes; this is because back-face culling is needed to avoid shading and aliasing
|
vertex. Normals then are computed automatically given the resulting global vertex positions and face information.
|
||||||
artifacts. When the skin is a closed 3D shape this does not matter because the back sides cannot be seen. But if the
|
Finally, the skin can be inflated by applying an offset to each vertex position along its (computed) normal.
|
||||||
skin is a 2D object, we have to specify both sides and offset them slightly to avoid artifacts. Note that the
|
Skins are one-sided for rendering purposes; this is because back-face culling is needed to avoid shading and aliasing
|
||||||
composite objects introduced in MuJoCo 2.0 generate skins automatically. So one can save an XML model with a composite
|
artifacts. When the skin is a closed 3D shape this does not matter because the back sides cannot be seen. But if the
|
||||||
object, and obtain an elaborate example of how a skin is specified in the XML.
|
skin is a 2D object, we have to specify both sides and offset them slightly to avoid artifacts. Note that the
|
||||||
| Similar to meshes, skins can be specified directly in the XML via attributes documented later, or loaded from a binary
|
composite objects introduced in MuJoCo 2.0 generate skins automatically. So one can save an XML model with a composite
|
||||||
SKN file which is in a custom format. The specification of skins is more complex than meshes because of the bone
|
object, and obtain an elaborate example of how a skin is specified in the XML.
|
||||||
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
|
Similar to meshes, skins can be specified directly in the XML via attributes documented later, or loaded from a binary
|
||||||
skin. ntexcoord can be zero or equal to nvertex. nbone specifies the number of MuJoCo bodies that will be used as
|
SKN file which is in a custom format. The specification of skins is more complex than meshes because of the bone
|
||||||
bones in the skin. The header is followed by the vertex, texcoord and face data, followed by a specification for each
|
subelements. The file format starts with a header of 4 integers: nvertex, ntexcoord, nface, nbone. The first three are
|
||||||
bone. The bone specification contains the name of the corresponding model body, 3D bind position, 4D bind quaterion,
|
the same as in meshes, and specify the total number of vertices, texture coordinate pairs, and triangle faces in the
|
||||||
number of vertices influenced by the bone, and the vertex index array and weight array. Body names are represented as
|
skin. ntexcoord can be zero or equal to nvertex. nbone specifies the number of MuJoCo bodies that will be used as
|
||||||
fixed-length character arrays and are expected to be 0-terminated. Characters after the first 0 are ignored. The
|
bones in the skin. The header is followed by the vertex, texcoord and face data, followed by a specification for each
|
||||||
contents of the SKN file are:
|
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
|
.. 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
|
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
|
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"`
|
: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
|
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.
|
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** (*)
|
: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
|
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
|
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
|
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>`.
|
: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
|
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
|
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
|
using the geom shape, a specified density or a geom mass which implies a density, and the assumption of uniform
|
||||||
density.
|
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
|
Geoms are not strictly required for physics simulation. One can create and simulate a model that only has bodies and
|
||||||
would be missing from such a simulation. We do not recommend using such models, but knowing that this is possible
|
joints. Such a model can even be visualized, using equivalent inertia boxes to represent bodies. Only contact forces
|
||||||
helps clarify the role of bodies and geoms in MuJoCo.
|
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`
|
:at:`name`: :at-val:`string, optional`
|
||||||
Name of the geom.
|
Name of the geom.
|
||||||
@@ -3978,19 +3984,19 @@ can also represent different forms of mechanical coupling.
|
|||||||
:width: 400px
|
:width: 400px
|
||||||
:align: right
|
:align: right
|
||||||
|
|
||||||
| This element creates a spatial tendon, which is a minimum-length path passing through specified via-points and
|
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
|
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>`
|
: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
|
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
|
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
|
tendon level. This example illustrates a multi-branch tendon acting as a finger extensor, with a counter-weight
|
||||||
instead of an actuator.
|
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
|
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
|
wrap around it. This is enabled automatically when a sidesite is specified and its position is inside the volume of
|
||||||
the obstacle geom.
|
the obstacle geom.
|
||||||
|
|
||||||
| `tendon.xml <_static/tendon.xml>`__
|
`tendon.xml <_static/tendon.xml>`__
|
||||||
|
|
||||||
:at:`name`: :at-val:`string, optional`
|
:at:`name`: :at-val:`string, optional`
|
||||||
Name of the tendon.
|
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
|
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.
|
visualizer to enable and disable the rendering of entire groups of actuators.
|
||||||
:at:`ctrllimited`: :at-val:`[false, true], "false"`
|
: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
|
If true, the control input to this actuator is automatically clamped to :at:`ctrlrange` at runtime. If false, control
|
||||||
clamping is disabled. Note that control input clamping can also be globally disabled with the clampctrl attribute of
|
input clamping is disabled. Note that control input clamping can also be globally disabled with the :at:`clampctrl`
|
||||||
option/ :ref:`flag <option-flag>`.
|
attribute of :ref:`option/flag <option-flag>`.
|
||||||
:at:`forcelimited`: :at-val:`[false, true], "false"`
|
: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.
|
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"`
|
: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.
|
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"`
|
: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.
|
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"`
|
:at:`lengthrange`: :at-val:`real(2), "0 0"`
|
||||||
Range of feasible lengths of the actuator's transmission. See :ref:`Length Range <CLengthRange>`.
|
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"`
|
:at:`gear`: :at-val:`real(6), "1 0 0 0 0 0"`
|
||||||
@@ -4262,12 +4275,13 @@ specify them independently.
|
|||||||
:el-prefix:`actuator/` **motor** (*)
|
:el-prefix:`actuator/` **motor** (*)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
| This and the next three elements are the :ref:`Actuator shortcuts <CActuator>` discussed earlier. When a
|
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
|
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
|
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
|
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.
|
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 element creates a direct-drive actuator. The underlying :el:`general` attributes are set as follows:
|
||||||
|
|
||||||
========= ======= ========= =======
|
========= ======= ========= =======
|
||||||
Attribute Setting Attribute Setting
|
Attribute Setting Attribute Setting
|
||||||
@@ -4277,8 +4291,8 @@ gaintype fixed gainprm 1 0 0
|
|||||||
biastype none biasprm 0 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::
|
.. |actuator/motor attrib list| replace::
|
||||||
@@ -4294,7 +4308,7 @@ biastype none biasprm 0 0 0
|
|||||||
:el-prefix:`actuator/` **position** (*)
|
: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
|
Attribute Setting Attribute Setting
|
||||||
@@ -4304,8 +4318,8 @@ gaintype fixed gainprm kp 0 0
|
|||||||
biastype affine biasprm 0 -kp 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::
|
.. |actuator/position attrib list| replace::
|
||||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
: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** (*)
|
: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
|
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
|
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:
|
inputs (reference position and reference velocity). The underlying :el:`general` attributes are set as follows:
|
||||||
|
|
||||||
========= ======= ========= =======
|
========= ======= ========= =======
|
||||||
Attribute Setting Attribute Setting
|
Attribute Setting Attribute Setting
|
||||||
@@ -4334,8 +4348,8 @@ gaintype fixed gainprm kv 0 0
|
|||||||
biastype affine biasprm 0 0 -kv
|
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::
|
.. |actuator/velocity attrib list| replace::
|
||||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
: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** (*)
|
:el-prefix:`actuator/` **cylinder** (*)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
| This element is suitable for modeling pneumatic or hidraulic cylinders. The underlying :el:`general` attributes are
|
This element is suitable for modeling pneumatic or hidraulic cylinders. The underlying :el:`general` attributes are
|
||||||
set as follows:
|
set as follows:
|
||||||
|
|
||||||
========= ======= ========= =============
|
========= ======= ========= =============
|
||||||
Attribute Setting Attribute Setting
|
Attribute Setting Attribute Setting
|
||||||
@@ -4363,8 +4377,8 @@ gaintype fixed gainprm area 0 0
|
|||||||
biastype affine biasprm bias(3)
|
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::
|
.. |actuator/cylinder attrib list| replace::
|
||||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
: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** (*)
|
:el-prefix:`actuator/` **muscle** (*)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
| This element is used to model a muscle actuator, as described in the :ref:`Muscles actuators <CMuscle>`
|
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:
|
section. The underlying :el:`general` attributes are set as follows:
|
||||||
|
|
||||||
========= ======= ========= ======================================================
|
========= ======= ========= ======================================================
|
||||||
Attribute Setting Attribute Setting
|
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
|
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::
|
.. |actuator/muscle attrib list| replace::
|
||||||
:at:`name`, :at:`class`, :at:`group`, :at:`ctrllimited`, :at:`forcelimited`, :at:`ctrlrange`, :at:`forcerange`,
|
: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** (*)
|
**sensor** (*)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
| This is a grouping element for sensor definitions. It does not have attributes. The outputs of all sensors are
|
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
|
concatenated in the field mjData.sensordata which has size mjModel.nsensordata. This data is not used in any internal
|
||||||
computations.
|
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
|
In addition to the sensors created with the elements below, the top-level function
|
||||||
corresponding to body accelerations and interaction forces. Some of these quantities are used to compute the output of
|
:ref:`mj_step` computes the quantities mjData.cacc, mjData.cfrc_int and mjData.crfc_ext
|
||||||
certain sensors (force, acceleration etc.) but even if no such sensors are defined in the model, these quantities
|
corresponding to body accelerations and interaction forces. Some of these quantities are used to compute the output of
|
||||||
themselves are "features" that could be of interest to the user.
|
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:
|
.. _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
|
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
|
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 child body, and the force points from the child towards the parent. The computation here takes into account all
|
||||||
the scale attribute. The computation here takes into account all forces acting on the system, including contacts as well
|
forces acting on the system, including contacts as well as external perturbations. Using this sensor often requires
|
||||||
as external perturbations. Using this sensor often requires creating a dummy body welded to its parent (i.e., having no
|
creating a dummy body welded to its parent (i.e., having no joint elements).
|
||||||
joint elements).
|
|
||||||
|
|
||||||
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
|
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
|
||||||
See :ref:`CSensor`.
|
See :ref:`CSensor`.
|
||||||
|
|||||||
+58
-1
@@ -2,6 +2,63 @@
|
|||||||
Changelog
|
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)
|
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
|
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>`.
|
#. 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
|
#. Added ``mj_printFormattedData``, which accepts a format string for floating point numbers, for example to increase
|
||||||
precision.
|
precision.
|
||||||
|
|||||||
+1
-1
@@ -314,7 +314,7 @@ Putting all this together, the net force in generalized coordinates contributed
|
|||||||
.. math::
|
.. math::
|
||||||
\sum_i \nabla l_i(q) \; p_i \left(u_i, w_i, l_i(q), \dot{l}_i(q, v) \right)
|
\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
|
with any user-defined forces in joint or Cartesian coordinates (which are stored in ``mjData.qfrc_applied`` and
|
||||||
``mjData.xfrc_applied`` respectively).
|
``mjData.xfrc_applied`` respectively).
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ sys.path.insert(0, os.path.abspath('../'))
|
|||||||
sys.path.append(os.path.abspath('ext'))
|
sys.path.append(os.path.abspath('ext'))
|
||||||
|
|
||||||
import sphinxcontrib.katex as katex # pylint: disable=g-import-not-at-top
|
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 -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ master_doc = 'index'
|
|||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
'sphinxcontrib.katex',
|
'sphinxcontrib.katex',
|
||||||
|
'sphinxcontrib.youtube',
|
||||||
'sphinx_reredirects',
|
'sphinx_reredirects',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
+290
-216
@@ -243,13 +243,13 @@ coordinates, but that effort is rarely justified.
|
|||||||
Frame orientations
|
Frame orientations
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Several model elements have right-handed spatial frames associated with them. These are all the elements defined in
|
Several model elements have right-handed spatial frames associated with them. These are all the elements defined in the
|
||||||
the kinematic tree except for joints. A spatial frame is defined by its position and orientation. Specifying 3D
|
kinematic tree except for joints. A spatial frame is defined by its position and orientation. Specifying 3D positions is
|
||||||
positions is straightforward, but specifying 3D orientations can be challenging. This is why MJCF provides several
|
straightforward, but specifying 3D orientations can be challenging. This is why MJCF provides several alternative
|
||||||
alternative mechanisms. No matter which mechanism the user chooses, the frame orientation is always represented as a
|
mechanisms. No matter which mechanism the user chooses, the frame orientation is always represented as a unit quaternion
|
||||||
unit quaternion after compilation. Recall that a 3D rotation by angle *a* around axis given by the unit vector (*x, y,
|
after compilation. Recall that a 3D rotation by angle :math:`a` around axis given by the unit vector :math:`(x, y, z)`
|
||||||
z*) corresponds to the quaternion (cos(*a*/2), sin(*a*/2) \* (*x, y, z*)). Also recall that every 3D orientation can
|
corresponds to the quaternion :math:`(\cos(a/2), \: \sin(a/2) \cdot (x, y, z))`. Also recall that every 3D orientation
|
||||||
be uniquely specified by a single 3D rotation by some angle around some axis.
|
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
|
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
|
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
|
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.
|
saved as MJCF, all frame orientations are expressed as quaternions using this attribute.
|
||||||
:at:`axisangle`: :at-val:`real(4), optional`
|
: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
|
These are the quantities :math:`(x, y, z, a)` mentioned above. The last number is the angle of rotation, in degrees
|
||||||
radians as specified by the :at:`angle` attribute of :ref:`compiler <compiler>`. The first three
|
or radians as specified by the :at:`angle` attribute of :ref:`compiler <compiler>`. The first three numbers determine
|
||||||
numbers determine a 3D vector which is the rotation axis. This vector is normalized to unit length during
|
a 3D vector which is the rotation axis. This vector is normalized to unit length during compilation, so the user can
|
||||||
compilation, so the user can specify a vector of any non-zero length. Keep in mind that the rotation is right-handed;
|
specify a vector of any non-zero length. Keep in mind that the rotation is right-handed; if the direction of the
|
||||||
if the direction of the vector (*x, y, z*) is reversed this will result in the opposite rotation. Changing the sign
|
vector :math:`(x, y, z)` is reversed this will result in the opposite rotation. Changing the sign of :math:`a` can
|
||||||
of *a* can also be used to specify the opposite rotation.
|
also be used to specify the opposite rotation.
|
||||||
:at:`euler`: :at-val:`real(3), optional`
|
:at:`euler`: :at-val:`real(3), optional`
|
||||||
Rotation angles around three coordinate axes. The sequence of axes around which these rotations are applied is
|
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
|
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
|
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.
|
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`
|
: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
|
The Z axis of the frame. The compiler finds the minimal rotation that maps the vector :math:`(0, 0, 1)` into the
|
||||||
specified here. This determines the X and Y axes of the frame implicitly. This is useful for geoms with rotational
|
vector specified here. This determines the X and Y axes of the frame implicitly. This is useful for geoms with
|
||||||
symmetry around the Z axis, as well as lights - which are oriented along the Z axis of their frame.
|
rotational symmetry around the Z axis, as well as lights - which are oriented along the Z axis of their frame.
|
||||||
|
|
||||||
.. _CSolver:
|
.. _CSolver:
|
||||||
|
|
||||||
Solver parameters
|
Solver parameters
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The solver :ref:`Parameters <soParameters>` section of the Computation chapter explained the
|
The solver :ref:`Parameters <soParameters>` section of the Computation chapter explained the mathematical and
|
||||||
mathematical and algorithmic meaning of the quantities d, b, k which determine the behavior of the constraints in
|
algorithmic meaning of the quantities :math:`d, b, k` which determine the behavior of the constraints in MuJoCo. Here we
|
||||||
MuJoCo. Here we explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and
|
explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and :at:`solimp` which are
|
||||||
:at:`solimp` which are available in all MJCF elements involving constraints. These parameters can be adjusted per
|
available in all MJCF elements involving constraints. These parameters can be adjusted per constraint, or per defaults
|
||||||
constraint, or per defaults class, or left undefined - in which case MuJoCo uses the internal defaults shown below.
|
class, or left undefined - in which case MuJoCo uses the internal defaults shown below. Note also the override mechanism
|
||||||
Note also the override mechanism available in :ref:`option <option>`; it can be used to change all
|
available in :ref:`option <option>`; it can be used to change all contact-related solver parameters at runtime, so as to
|
||||||
contact-related solver parameters at runtime, so as to experiment interactively with parameter settings or implement
|
experiment interactively with parameter settings or implement continuation methods for numerical optimization.
|
||||||
continuation methods for numerical optimization.
|
|
||||||
|
|
||||||
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let a1
|
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let
|
||||||
denote the acceleration, v the velocity, r the position or residual (defined as 0 in friction dimensions), k and b the
|
:math:`a_1` denote the acceleration, :math:`v` the velocity, :math:`r` the position or residual (defined as 0 in
|
||||||
stiffness and damping of the virtual spring used to define the reference acceleration aref = -b*v - k*r. Let d be the
|
friction dimensions), :math:`k` and :math:`b` the stiffness and damping of the virtual spring used to define the
|
||||||
constraint impedance, and a0 the acceleration in the absence of constraint force. Our earlier analysis revealed that
|
reference acceleration :math:`a_{\rm ref} = -b v - k r`. Let :math:`d` be the constraint impedance, and :math:`a_0` the
|
||||||
the dynamics in constraint space are approximately
|
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.
|
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
|
First we explain the setting of the impedance :math:`d`. Recall that :math:`d` must lie between 0 and 1; internally
|
||||||
to the range [:ref:`mjMINIMP mjMAXIMP <glNumeric>`] which is currently set to [0.0001 0.9999]. It
|
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
|
causes the solver to interpolate between the unforced acceleration :math:`a_0` and reference acceleration
|
||||||
d correspond to soft/weak constraints while large values of d correspond to strong/hard constraints. The user can set
|
:math:`a_{\rm ref}`. Small values of :math:`d` correspond to soft/weak constraints while large values of :math:`d`
|
||||||
d to a constant, or take advantage of its interpolating property and make it position-dependent, i.e., a function of r.
|
correspond to strong/hard constraints. The user can set :math:`d` to a constant, or take advantage of its interpolating
|
||||||
Position-dependent impedance can be used to model soft contact layers around objects, or define equality constraints
|
property and make it position-dependent, i.e., a function of :math:`r`. Position-dependent impedance can be used to
|
||||||
that become stronger with larger violation (so as to approximate backlash for example). The shape of the function d(r)
|
model soft contact layers around objects, or define equality constraints that become stronger with larger violation (so
|
||||||
is determined by the element-specific parameter vector :at:`solimp`.
|
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"
|
**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
|
The five numbers are (dmin, dmax, width, midpoint, power). They parameterize the function :math:`d(r)`. Prior to
|
||||||
expanded the family of impedance functions while keeping it backward-compatible as follows. The user is allowed to
|
MuJoCo 2.0 this attribute had three parameters, plus a global option specifying the shape of the function. In MuJoCo
|
||||||
set only the first three parameters, whose defaults are the same as in prior releases. The defaults for the last two
|
2.0 we expanded the family of impedance functions while keeping it backward-compatible as follows. The user is
|
||||||
parameters then generate the same function which was the default in prior releases (a sigmoid). The new
|
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
|
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
|
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,
|
:math:`d(r)` depends on the absolute value of :math:`r`. This flexibility was added to allow better control of remote
|
||||||
and can also be used for other constraints. The power (of the polynomial spline used to generate the function) must
|
contact forces, and can also be used for other constraints. The power (of the polynomial spline used to generate the
|
||||||
be 1 or greater. The midpoint (specifying the inflection point) must be between 0 and 1, and is expressed in units of
|
function) must be 1 or greater. The midpoint (specifying the inflection point) must be between 0 and 1, and is
|
||||||
width. Note that when the power is 1, the function is linear regardless of the midpoint.
|
expressed in units of width. Note that when the power is 1, the function is linear regardless of the midpoint.
|
||||||
|image0|
|
|image0|
|
||||||
|
|
||||||
These plots show the impedance d(r) on the vertical axis, as a function of the constraint violation r on the
|
These plots show the impedance :math:`d(r)` on the vertical axis, as a function of the constraint violation :math:`r`
|
||||||
horizontal axis. The quantity r is computed as follows. For equality constraints, r equals the constraint violation
|
on the horizontal axis. The quantity :math:`r` is computed as follows. For equality constraints, :math:`r` equals the
|
||||||
which can be either positive or negative. For friction loss or friction dimensions of elliptic cones, r is always 0.
|
constraint violation which can be either positive or negative. For friction loss or friction dimensions of elliptic
|
||||||
For limits, normal directions of elliptic cones and all directions of pyramidal cones, r is the (limit or contact)
|
cones, :math:`r` is always 0. For limits, normal directions of elliptic cones and all directions of pyramidal cones,
|
||||||
distance minus the margin at which the constraint becomes active; for contacts this margin is actually margin-gap.
|
:math:`r` is the (limit or contact) distance minus the margin at which the constraint becomes active; for contacts
|
||||||
Therefore limit and contact constraints are active when the corresponding r is negative.
|
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
|
Next we explain the setting of the stiffness :math:`k` and damping :math:`b`. The idea here is to re-parameterize the
|
||||||
the time constant and damping ratio of the above mass-spring-damper system. By "time constant" we mean the inverse of
|
model in terms of the time constant and damping ratio of the above mass-spring-damper system. By "time constant" we mean
|
||||||
the natural frequency times the damping ratio. Constraints whose residual is identically 0 have first-order dynamics and
|
the inverse of the natural frequency times the damping ratio. Constraints whose residual is identically 0 have first-
|
||||||
the mass-spring-damper analysis does not apply. In that case the time constant is the rate of exponential decay of the
|
order dynamics and the mass-spring-damper analysis does not apply. In that case the time constant is the rate of
|
||||||
constraint velocity, and the damping ratio is ignored. In addition to this format, MuJoCo 2.0 allows a second format
|
exponential decay of the constraint velocity, and the damping ratio is ignored. In addition to this format, MuJoCo 2.0
|
||||||
where stiffness and damping are specified more directly.
|
allows a second format where stiffness and damping are specified more directly.
|
||||||
|
|
||||||
**solref :** real(2), "0.02 1"
|
**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
|
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.
|
specification is considered to be in the :math:`(\text{timeconst}, \text{dampratio})` format which has been available
|
||||||
Otherwise the specification is considered to be in the new (-stiffness, -damping) format introduced in MuJoCo 2.0.
|
in MuJoCo all along. Otherwise the specification is considered to be in the new :math:`(-\text{stiffness}, -
|
||||||
We first describe the original format where the two numbers are (timeconst, dampratio). In this case we use a
|
\text{damping})`, format introduced in MuJoCo 2.0. We first describe the original format where the two numbers are
|
||||||
mass-spring-damper model to compute k, b after suitable scaling. Note that the effective stiffness d(r)*k and damping
|
:math:`(\text{timeconst}, \text{dampratio})`. In this case we use a mass-spring-damper model to compute :math:`k, b`
|
||||||
d(r)*b are scaled by the impedance d(r) which is a function of the distance r. Thus we cannot always achieve the
|
after suitable scaling. Note that the effective stiffness :math:`d(r) \cdot k` and damping :math:`d(r) \cdot b` are
|
||||||
specified mass-spring-damper properties, unless we completely undo the scaling by d. But the latter is undesirable
|
scaled by the impedance :math:`d(r)` which is a function of the distance :math:`r`. Thus we cannot always achieve the
|
||||||
because it would ruin the interpolating property, in particular the limit d = 0 would no longer disable the
|
specified mass-spring-damper properties, unless we completely undo the scaling by :math:`d`. But the latter is
|
||||||
constraint. Instead we scale the stiffness and damping so that the damping ratio remains constant, while the time
|
undesirable because it would ruin the interpolating property, in particular the limit :math:`d=0` would no longer
|
||||||
constant increases when d(r) gets smaller. The scaling formulas are
|
disable the constraint. Instead we scale the stiffness and damping so that the damping ratio remains constant, while
|
||||||
b = 2 / (dmax \* timeconst)
|
the time constant increases when :math:`d(r)` gets smaller. The scaling formulas are
|
||||||
k = d(r) / (dmax \* dmax \* timeconst \* timeconst \* dampratio \* dampratio)
|
|
||||||
|
.. 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
|
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
|
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
|
can go unstable. This is enforced internally, unless the :at:`refsafe` attribute of :ref:`flag <option-flag>` is set
|
||||||
:ref:`flag <option-flag>` is set to false. The dampratio parameter would normally be set to 1,
|
to false. The :math:`\text{dampratio}` parameter would normally be set to 1, corresponding to critical damping.
|
||||||
corresponding to critical damping. Smaller values result in under-damped or bouncy constraints, while larger values
|
Smaller values result in under-damped or bouncy constraints, while larger values result in over-damped constraints.
|
||||||
result in over-damped constraints.
|
Next we describe the new format where the two numbers are :math:`(-\text{stiffness}, -\text{damping})`. This allows
|
||||||
Next we describe the new format where the two numbers are (-stiffness, -damping). This allows more direct control
|
more direct control over restitution in particular. We still apply some scaling so that the same numbers can be used
|
||||||
over restitution in particular. We still apply some scaling so that the same numbers can be used with different
|
with different impedances, but the scaling no longer depends on :math:`r` and the two numbers no longer interact. The
|
||||||
impedances, but the scaling no longer depends on r and the two numbers no longer interact. The scaling formulas are
|
scaling formulas are
|
||||||
b = damping / dmax
|
|
||||||
k = stiffness / (dmax \* dmax)
|
.. math::
|
||||||
|
\begin{aligned}
|
||||||
|
b &= \text{damping} / d_\text{max} \\
|
||||||
|
k &= \text{stiffness} / d_\text{max}^2 \\
|
||||||
|
\end{aligned}
|
||||||
|
|
||||||
.. _CContact:
|
.. _CContact:
|
||||||
|
|
||||||
@@ -530,20 +544,18 @@ well as solver statistics per iteration. We can offer the following general guid
|
|||||||
Actuator shortcuts
|
Actuator shortcuts
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
As explained in the :ref:`Actuation model <geActuation>` section of the Computation chapter, MuJoCo
|
As explained in the :ref:`Actuation model <geActuation>` section of the Computation chapter, MuJoCo offers a flexible
|
||||||
offers a flexible actuator model with transmission, activation dynamics and force generation components that can be
|
actuator model with transmission, activation dynamics and force generation components that can be specified
|
||||||
specified independently. The full functionality can be accessed via the XML element
|
independently. The full functionality can be accessed via the XML element :ref:`general <general>` which allows the user
|
||||||
:ref:`general <general>` which allows the user to create a variety of custom actuators. In addition,
|
to create a variety of custom actuators. In addition, MJCF provides shortcuts for configuring common actuators. This is
|
||||||
MJCF provides shortcuts for configuring common actuators. This is done via the XML elements
|
done via the XML elements :ref:`motor <motor>`, :ref:`position <position>`, :ref:`velocity <velocity>`, :ref:`cylinder
|
||||||
:ref:`motor <motor>`, :ref:`position <position>`,
|
<cylinder>`, :ref:`muscle <muscle>`. These are *not* separate model elements. Internally MuJoCo supports only one
|
||||||
: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
|
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
|
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
|
different names. For example, :el:`position` creates a position servo with attribute :at:`kp` which is the servo gain.
|
||||||
gain. However :el:`general` does not have an attribute :at:`kp`. Instead the parser adjusts the gain and bias
|
However :el:`general` does not have an attribute :at:`kp`. Instead the parser adjusts the gain and bias parameters of
|
||||||
parameters of the general actuator in a coordinated way so as to mimic a position servo. The same effect could have
|
the general actuator in a coordinated way so as to mimic a position servo. The same effect could have been achieved by
|
||||||
been achieved by using :el:`general` directly, and setting its attributes to certain values as described below.
|
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
|
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
|
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
|
create multiple defaults classes, or avoid using defaults for actuators and instead specify all their attributes
|
||||||
explicitly.
|
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:
|
.. _CLengthRange:
|
||||||
|
|
||||||
Actuator length range
|
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
|
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.
|
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)
|
First we discuss length and length scaling. The range of feasible lengths of the transmission (i.e., MuJoCo tendon) will
|
||||||
will play an important role; see :ref:`Length range <CLengthRange>` section above. In biomechanics, a muscle and a
|
play an important role; see :ref:`Length range <CLengthRange>` section above. In biomechanics, a muscle and a tendon are
|
||||||
tendon are attached in series and form a muscle-tendon actuator. Our convention is somewhat different: in MuJoCo the
|
attached in series and form a muscle-tendon actuator. Our convention is somewhat different: in MuJoCo the entity that
|
||||||
entity that has spatial properties (in particular length and velocity) is the tendon, while the muscle is an abstract
|
has spatial properties (in particular length and velocity) is the tendon, while the muscle is an abstract force-
|
||||||
force-generating mechanism that pulls on the tendon. Thus the tendon length in MuJoCo corresponds to the muscle+tendon
|
generating mechanism that pulls on the tendon. Thus the tendon length in MuJoCo corresponds to the muscle+tendon length
|
||||||
length in biomechanics. We assume that the biological tendon is inelastic, with constant length LT, while the
|
in biomechanics. We assume that the biological tendon is inelastic, with constant length :math:`L_T`, while the
|
||||||
biological muscle length LM varies over time. The MuJoCo tendon length is the sum of the biological muscle and tendon
|
biological muscle length :math:`L_M` varies over time. The MuJoCo tendon length is the sum of the biological muscle and
|
||||||
lengths:
|
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
|
Another important constant is the optimal resting length of the muscle, denoted :math:`L_0`. It equals the length
|
||||||
the muscle generates maximum active force at zero velocity. We do not ask the user to specify L0 and LT directly,
|
:math:`L_M` at which the muscle generates maximum active force at zero velocity. We do not ask the user to specify
|
||||||
because it is difficult to know their numeric values given the spatial complexity of the tendon routing and wrapping.
|
:math:`L_0` and :math:`L_T` directly, because it is difficult to know their numeric values given the spatial complexity
|
||||||
Instead we compute L0 and LT automatically as follows. The length range computation described above already provided
|
of the tendon routing and wrapping. Instead we compute :math:`L_0` and :math:`L_T` automatically as follows. The length
|
||||||
the operating range for LT + LM. In addition, we ask the user to specify the operating range for the muscle length LM
|
range computation described above already provided the operating range for :math:`L_T+L_M`. In addition, we ask the user
|
||||||
scaled by the (still unknown) constant L0. This is done with the attribute range; the default scaled range is (0.75,
|
to specify the operating range for the muscle length :math:`L_M` scaled by the (still unknown) constant :math:`L_0`.
|
||||||
1.05). Now we can compute the two constants, using the fact that the actual and scaled ranges have to map to each
|
This is done with the attribute range; the default scaled range is :math:`(0.75, 1.05)`. Now we can compute the two
|
||||||
other:
|
constants, using the fact that the actual and scaled ranges have to map to each other:
|
||||||
|
|
||||||
(actuator_lengthrange[0] - LT) / L0 = range[0]
|
.. math::
|
||||||
|
\begin{aligned}
|
||||||
(actuator_lengthrange[1] - LT) / L0 = range[1]
|
(\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:
|
At runtime, we compute the scaled muscle length and velocity as:
|
||||||
|
|
||||||
L = (actuator_length - LT) / L0
|
.. math::
|
||||||
|
\begin{aligned}
|
||||||
V = actuator_velocity / L0
|
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
|
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
|
captured by the Force-Length-Velocity (:math:`\text{\small FLV}`) function measured in many experimental papers. We
|
||||||
function as follows:
|
approximate this function as follows:
|
||||||
|
|
||||||
|image1|
|
|image1|
|
||||||
|
|
||||||
The function is in the form:
|
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
|
Comparing to the general form of a MuJoCo actuator, we see that :math:`F_L\cdot F_V` is the actuator gain and
|
||||||
bias. FL is the active force as a function of length, while FV is the active force as a function of velocity. They are
|
: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
|
||||||
multiplied to obtain the overall active force (note the scaling by act which is the actuator activation). FP is the
|
active force as a function of velocity. They are multiplied to obtain the overall active force (note the scaling by act
|
||||||
passive force which is always present regardless of activation. The output of the FLV function is the scaled muscle
|
which is the actuator activation). :math:`F_P` is the passive force which is always present regardless of activation.
|
||||||
force. We multiply the scaled force by a muscle-specific constant F0 to obtain the actual force:
|
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
|
The negative sign is because positive muscle activation generates pulling force. The constant :math:`F_0` is the peak
|
||||||
force at zero velocity. It is related to the muscle thickness (i.e., physiological cross-sectional area or PCSA). If
|
active force at zero velocity. It is related to the muscle thickness (i.e., physiological cross-sectional area or PCSA).
|
||||||
known, it can be set with the attribute force of element :ref:`muscle <muscle>`. If it is not known, we
|
If known, it can be set with the attribute force of element :ref:`muscle <muscle>`. If it is not known, we set it to
|
||||||
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
|
:math:`-1` which is the default. In that case we rely on the fact that larger muscles tend to act on joints that move
|
||||||
move more weight. The attribute scale defines this relationship as:
|
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
|
The quantity :math:`\texttt{actuator\_acc0}` is precomputed by the model compiler. It is the norm of the joint
|
||||||
unit force acting on the actuator transmission. Intuitively, scale determines how strong the muscle is "on average"
|
acceleration caused by unit force acting on the actuator transmission. Intuitively, :math:`\text{scale}` determines how
|
||||||
while its actual strength depends on the geometric and inertial properties of the entire model.
|
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,
|
Thus far we encountered three constants that define the properties of an individual muscle: :math:`L_T, L_0, F_0`. In
|
||||||
the function FLV itself has several parameters illustrated in the above figure: lmin, lmax, vmax, fpmax, fvmax. These
|
addition, the function :math:`\text{\small FLV}` itself has several parameters illustrated in the above figure:
|
||||||
are supposed to be the same for all muscles, however different experimental papers suggest different shapes of the FLV
|
:math:`l_\text{min}, l_\text{max}, v_\text{max}, f_\text{pmax}, f_\text{vmax}`. These are supposed to be the same for
|
||||||
function, thus users familiar with that literature may want to adjust them. We provide the MATLAB function
|
all muscles, however different experimental papers suggest different shapes of the FLV function, thus users familiar
|
||||||
`FLV.m <_static/FLV.m>`__ which was used to generate the above figure and shows how we compute the FLV function.
|
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
|
Before embarking on a mission to design more accurate :math:`\text{\small FLV}` functions, consider the fact that the
|
||||||
muscle has a bigger effect than the shape of the FLV function, and in many cases this parameter is unknown. Below is a
|
operating range of the muscle has a bigger effect than the shape of the :math:`\text{\small FLV}` function, and in many
|
||||||
graphical illustration:
|
cases this parameter is unknown. Below is a graphical illustration:
|
||||||
|
|
||||||
|image2|
|
|image2|
|
||||||
|
|
||||||
This figure format is common in the biomechanics literature, showing the operating range of each muscle superimposed
|
This figure format is common in the biomechanics literature, showing the operating range of each muscle superimposed on
|
||||||
on the normalized FL curve (ignore the vertical displacement). Our default range is shown in black. The blue curves
|
the normalized :math:`\text{FL}` curve (ignore the vertical displacement). Our default range is shown in black. The blue
|
||||||
are experimental data for two arm muscles. One can find muscles with small range, large range, range spanning the
|
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
|
ascending portion of the :math:`\text{FL}` curve, or the descending portion, or some of both. Now suppose you have a
|
||||||
muscles. Do you believe that someone did careful experiments and measured the operating range for every muscle in your
|
model with 50 muscles. Do you believe that someone did careful experiments and measured the operating range for every
|
||||||
model, taking into account all the joints that the muscle spans? If not, then it is better to think of
|
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
|
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
|
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.
|
modelers consider constant and known, there is an experimental paper showing that they vary under some conditions. This
|
||||||
This is not to discourage people from building accurate models, but rather to discourage people from believing too
|
is not to discourage people from building accurate models, but rather to discourage people from believing too strongly
|
||||||
strongly in their models. Modeling in biology is quite different from modeling in physics and engineering... which is
|
in their models. Modeling in biology is quite different from modeling in physics and engineering... which is why we find
|
||||||
why we find it ironic when people in Robotics complain that building accurate robot models is hard.
|
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
|
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:
|
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
|
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
|
are two time constants specified with the attribute timeconst, namely :math:`\text{timeconst} = (\tau_\text{act},
|
||||||
(0.01, 0.04). The effective time constant tau is then computed at runtime as:
|
\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
|
.. math::
|
||||||
|
\tau(\texttt{ctrl}, \texttt{act}) =
|
||||||
tau(ctrl, act) = tau_deact / (0.5 + 1.5*act), if ctrl <= 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,
|
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
|
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
|
This can be adjusted separately for each muscle, but it makes more sense to set it once in the
|
||||||
:ref:`default <default>` element.
|
:ref:`default <default>` element.
|
||||||
force
|
force
|
||||||
If you know the peak active force F0 of the individual muscles, enter it here. Many experimental papers contain this
|
If you know the peak active force :math:`F_0` of the individual muscles, enter it here. Many experimental papers
|
||||||
data.
|
contain this data.
|
||||||
range
|
range
|
||||||
The operating range of the muscle in scaled lengths is also available in some papers. It is not clear how reliable
|
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
|
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
|
timeconst
|
||||||
Muscles are composed of slow-twitch and fast-twitch fibers. The typical muscle is mixed, but some muscles have a
|
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
|
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
|
lmin, lmax, vmax, fpmax, fvmax
|
||||||
These are the parameters controlling the shape of the FLV function. Advanced users can experiment with them; see
|
These are the parameters controlling the shape of the :math:`\text{\small FLV}` function. Advanced users can
|
||||||
MATLAB function `FLV.m <_static/FLV.m>`__. Similar to the scale setting, if you want to change the FLV
|
experiment with them; see MATLAB function `FLV.m <_static/FLV.m>`__. Similar to the scale setting, if you want to
|
||||||
parameters for all muscles, do so in the :ref:`default <default>` element.
|
change the :math:`\text{\small FLV}` parameters for all muscles, do so in the :ref:`default <default>` element.
|
||||||
Custom model
|
Custom model
|
||||||
Instead of adjusting the parameters of our muscle model, users can implement a different model, by setting gaintype,
|
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
|
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 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
|
The :math:`\text{\small FLV}` function is not exactly the same, but both MuJoCo and OpenSim approximate the same
|
||||||
are very close. For a description of the OpenSim model and summary of relevant experimental data, see:
|
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>`__.
|
||||||
Millard et al, "Flexing computational muscle: modeling and simulation of musculotendon dynamics", J Biomech Eng. 2013
|
|
||||||
Feb;135(2)
|
|
||||||
|
|
||||||
We assume inelastic tendons while OpenSim can model tendon elasticity. We decided not to do that here, because tendon
|
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
|
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
|
instability. In practice tendons are quite stiff, and their effect can be captured approximately by stretching the
|
||||||
curve corresponding to the inelastic case (Zajac 89). This can be done in MuJoCo by shortening the muscle operating
|
:math:`\text{FL}` curve corresponding to the inelastic case (`Zajac (1989)
|
||||||
range.
|
<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
|
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.
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
||||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||||
</composite>
|
</composite>
|
||||||
</worldbody>
|
</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
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
|
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
|
||||||
<joint kind="main" damping="0.001"/>
|
<joint kind="main" damping="0.001"/>
|
||||||
<tendon kind="main" width="0.01"/>
|
<tendon kind="main" width="0.01"/>
|
||||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||||
<pin coord="1"/>
|
<pin coord="1"/>
|
||||||
<pin coord="13"/>
|
<pin coord="13"/>
|
||||||
</composite>
|
</composite>
|
||||||
|
|
||||||
The grid type can create 1D or 2D grids, depending on the :at:`count` attribute. Here we illustrate 1D grids. These
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
||||||
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
|
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
|
||||||
<geom size=".02"/>
|
<geom size=".02"/>
|
||||||
<pin coord="0 0"/>
|
<pin coord="0 0"/>
|
||||||
<pin coord="8 0"/>
|
<pin coord="8 0"/>
|
||||||
</composite>
|
</composite>
|
||||||
|
|
||||||
A 2D grid can be used to simulate cloth. What it really simulates is a 2D grid of spheres connected with
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<body name="B10" pos="0 0 1">
|
<body name="B10" pos="0 0 1">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
||||||
<joint kind="main" damping="0.005"/>
|
<joint kind="main" damping="0.005"/>
|
||||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||||
</composite>
|
</composite>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
The remaining composite object types create kinematic trees of element bodies, and the parent body becomes the root of
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<body name="B3_5" pos="0 0 1">
|
<body name="B3_5" pos="0 0 1">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
|
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
|
||||||
<joint kind="main" damping="0.001"/>
|
<joint kind="main" damping="0.001"/>
|
||||||
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
|
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
|
||||||
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
|
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
|
||||||
</composite>
|
</composite>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
The cloth type is an alternative to a 2D grid, and has somewhat different properties. Similar to rope vs. 1D grid, the
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<body pos="0 0 1">
|
<body pos="0 0 1">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<composite type="box" count="7 7 7" spacing="0.04">
|
<composite type="box" count="7 7 7" spacing="0.04">
|
||||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||||
</composite>
|
</composite>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
The box type, as well as the cylinder and ellipsoid types below, are used to model soft 3D objects. The element bodies
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<body pos="0 0 1">
|
<body pos="0 0 1">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
|
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
|
||||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||||
</composite>
|
</composite>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
Cylinders and ellipsoids are created in the same way as boxes. The only difference is that the reference positions of
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<robot name="darwin">
|
<robot name="darwin">
|
||||||
<mujoco>
|
<mujoco>
|
||||||
<compiler meshdir="../mesh/darwin/" balanceinertia="true"/>
|
<compiler meshdir="../mesh/darwin/" balanceinertia="true"/>
|
||||||
</mujoco>
|
</mujoco>
|
||||||
<link name="MP_BODY">
|
<link name="MP_BODY">
|
||||||
...
|
...
|
||||||
</robot>
|
</robot>
|
||||||
|
|
||||||
The above extensions make URDF more usable but still limited. If the user wants to build models taking full advantage of
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<joint name="J1" type="hinge" pos="0 0 0" axis="0 0 1" armature="0.01"/>
|
<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="J2" type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="-1 1"/>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
Thus the overall rotation of the body relative to its parent is J1+J2. Now define an actuator acting only on J1. The
|
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
|
.. code-block:: xml
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<geom type="plane" size="1 1 .1"/>
|
<geom type="plane" size="1 1 .1"/>
|
||||||
|
|
||||||
<body pos="0 0 1">
|
<body pos="0 0 1">
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<geom type="sphere" size="0.1" solref="-1000 0"/>
|
<geom type="sphere" size="0.1" solref="-1000 0"/>
|
||||||
</body>
|
</body>
|
||||||
</worldbody>
|
</worldbody>
|
||||||
|
|
||||||
.. _CSize:
|
.. _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
|
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.
|
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:
|
.. _NotObject:
|
||||||
|
|
||||||
Not object-oriented
|
Not object-oriented
|
||||||
@@ -707,7 +733,7 @@ first, followed by the limits of the second joint etc. This ordering reflects th
|
|||||||
row-major format.
|
row-major format.
|
||||||
|
|
||||||
The available element types are defined in
|
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
|
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.
|
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
|
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
|
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
|
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 -
|
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
|
-- 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 user.
|
||||||
|
|
||||||
The following example illustrates the point that multiple sites and geoms can be attached to the same body: two sites
|
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
|
Programming
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
.. _inIntro:
|
||||||
|
|
||||||
Introduction
|
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
|
library exposes the full functionality of the simulator through a compiler-independent shared-memory C API. It can also
|
||||||
be used in C++ programs.
|
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
|
The MuJoCo codebase is organized into subdirectories corresponding to different major areas of functionality:
|
||||||
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:
|
|
||||||
|
|
||||||
|
Engine
|
||||||
|
The simulator (or physics engine) is written in C. It is responsible for all runtime computations.
|
||||||
Parser
|
Parser
|
||||||
The XML parser is written in C++. It can parse MJCF models and URDF models, converting them into an internal mjCModel
|
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.
|
C++ object which is not directly exposed to the user.
|
||||||
Compiler
|
Compiler
|
||||||
The compiler is written in C++. It takes an mjCModel C++ object constructed by the parser, and converts it into an
|
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.
|
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
|
Abstract visualizer
|
||||||
The abstract visualizer is written in C. It generates a list of abstract geometric entities representing the
|
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
|
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
|
Getting started
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The software distribution is a single .zip (Windows) or .tar.gz (Mac and Linux) archive whose name contains the platform
|
MuJoCo is an open source project. Pre-built dynamic libraries are available for x86_64 and arm64 machines running
|
||||||
and software version, e.g. mujoco210_windows.zip. There is no installer. Simply unzip this archive in a directory of
|
Windows, Linux, and macOS. These can be downloaded from the `GitHub Releases page <https://github.com/deepmind/mujoco/releases>`_.
|
||||||
your choice (where you have write access). You may need to use chmod to set execute permissions or otherwise give
|
Users who do not intend to develop or modify core MuJoCo code are encouraged to use our pre-built libraries, as these
|
||||||
permissions to run the libraries. From the bin subdirectory, you can now run the precompiled code samples, for example:
|
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
|
.. code-block:: Text
|
||||||
|
|
||||||
Windows: simulate ..\model\humanoid.xml
|
Windows: simulate ..\model\humanoid.xml
|
||||||
Linux and macOS: ./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
|
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
|
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.
|
directory; it contains error and warning messages, and can be deleted at any time.
|
||||||
|
|
||||||
.. code-block:: Text
|
.. code-block:: Text
|
||||||
|
|
||||||
mujoco210
|
bin - dynamic libraries, executables, MUJOCO_LOG.TXT
|
||||||
bin - dynamic libraries, executables, MUJOCO_LOG.TXT
|
doc - README.txt and REFERENCE.txt
|
||||||
doc - README.txt and REFERENCE.txt
|
include - header files needed to develop with MuJoCo
|
||||||
include - header files needed to develop with MuJoCo
|
model - model collection
|
||||||
model - model collection (extra models available on the Forum)
|
sample - code samples and makefile need to build them
|
||||||
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
|
After verifying that the simulator works, you may also want to re-compile the code samples to ensure that you have a
|
||||||
development environment is properly installed. The distribution includes a platform-specific makefile in the sample
|
working development environment. We provide Makefiles for `Windows <https://github.com/deepmind/mujoco/blob/main/sample/Makefile.windows>`_,
|
||||||
subdirectory, which assumes Visual Studio on Windows, GCC on Linux and Clang on macOS. On Windows, remember to open a
|
`macOS <https://github.com/deepmind/mujoco/blob/main/sample/Makefile.macos>`_, and
|
||||||
Visual Studio command prompt with native x64 tools. Assuming the compilation succeeded and the resulting executables in
|
`Linux <https://github.com/deepmind/mujoco/blob/main/sample/Makefile>`_, and also a cross-platform
|
||||||
the bin subdirectory work, you are ready to start developing with MuJoCo.
|
`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
|
On macOS, the DMG disk image contains ``MuJoCo.app``, which you can double-click to launch the ``simulate`` GUI.
|
||||||
compiler of their choice. In practice we are using C++11 features as well as std:: functionality internally, and despite
|
You can also drag ``MuJoCo.app`` into the ``/Application`` on your system, as you would to install any other app.
|
||||||
our efforts to statically link all necessary runtime libraries, this is not always possible - especially on Linux where
|
While ``MuJoCo.app`` may look like a file, it is in fact an `Application Bundle <https://developer.apple.com/go/?id=bundle-structure>`_,
|
||||||
licensing restrictions prevent static linking. If MuJoCo fails to start because of missing or incompatible dynamic
|
which is a directory that contains executable binaries for all of MuJoCo's sample applications, along with an embedded
|
||||||
libraries, please install the necessary libraries.
|
`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:
|
.. _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
|
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.
|
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
|
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.
|
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
|
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.
|
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
|
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
|
read their inputs and write their outputs. It also defines primitive types and other structures needed to define
|
||||||
mjData.
|
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.
|
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.
|
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.
|
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`.
|
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
|
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
|
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>`.
|
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
|
Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client
|
||||||
code.
|
code.
|
||||||
glfw3.h
|
glfw3.h
|
||||||
@@ -152,7 +178,7 @@ the symbol :ref:`mjVERSION_HEADER <glNumeric>` and the library provides the func
|
|||||||
|
|
||||||
// recommended version check
|
// recommended version check
|
||||||
if( mjVERSION_HEADER!=mj_version() )
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
// simulate until t = 10 seconds
|
||||||
while( d->time<10 )
|
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.
|
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
|
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
|
// simple controller applying damping to each dof
|
||||||
void mycontroller(const mjModel* m, mjData* d)
|
void mycontroller(const mjModel* m, mjData* d)
|
||||||
{
|
{
|
||||||
if( m->nu==m->nv )
|
if( m->nu==m->nv )
|
||||||
mju_scl(d->ctrl, d->qvel, -0.1, 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
|
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
|
.. code-block:: C
|
||||||
|
|
||||||
while( d->time<10 )
|
while( d->time<10 ) {
|
||||||
{
|
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
mj_step(m, d);
|
||||||
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?
|
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
|
.. code-block:: C
|
||||||
|
|
||||||
while( d->time<10 )
|
while( d->time<10 ) {
|
||||||
{
|
mj_step1(m, d);
|
||||||
mj_step1(m, d);
|
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
||||||
// set d->ctrl or d->qfrc_applied or d->xfrc_applied
|
mj_step2(m, d);
|
||||||
mj_step2(m, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
There is one complication however: this only works with Euler integration. The Runge-Kutta integrator (as well as other
|
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
|
.. code-block:: C
|
||||||
|
|
||||||
void mj_step(const mjModel* m, mjData* d)
|
void mj_step(const mjModel* m, mjData* d) {
|
||||||
{
|
// common to all integrators
|
||||||
// common to all integrators
|
mj_checkPos(m, d);
|
||||||
mj_checkPos(m, d);
|
mj_checkVel(m, d);
|
||||||
mj_checkVel(m, d);
|
mj_forward(m, d);
|
||||||
mj_forward(m, d);
|
mj_checkAcc(m, d);
|
||||||
mj_checkAcc(m, d);
|
|
||||||
|
|
||||||
// compare forward and inverse solutions if enabled
|
// compare forward and inverse solutions if enabled
|
||||||
if( mjENABLED(mjENBL_FWDINV) )
|
if( mjENABLED(mjENBL_FWDINV) )
|
||||||
mj_compareFwdInv(m, d);
|
mj_compareFwdInv(m, d);
|
||||||
|
|
||||||
// use selected integrator
|
// use selected integrator
|
||||||
if( m->opt.integrator==mjINT_RK4 )
|
if( m->opt.integrator==mjINT_RK4 )
|
||||||
mj_RungeKutta(m, d, 4);
|
mj_RungeKutta(m, d, 4);
|
||||||
else
|
else
|
||||||
mj_Euler(m, d);
|
mj_Euler(m, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
The checking functions reset the simulation automatically if any numerical values have become invalid or too large.
|
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)
|
void mj_step1(const mjModel* m, mjData* d)
|
||||||
{
|
{
|
||||||
mj_checkPos(m, d);
|
mj_checkPos(m, d);
|
||||||
mj_checkVel(m, d);
|
mj_checkVel(m, d);
|
||||||
mj_fwdPosition(m, d);
|
mj_fwdPosition(m, d);
|
||||||
mj_sensorPos(m, d);
|
mj_sensorPos(m, d);
|
||||||
mj_energyPos(m, d);
|
mj_energyPos(m, d);
|
||||||
mj_fwdVelocity(m, d);
|
mj_fwdVelocity(m, d);
|
||||||
mj_sensorVel(m, d);
|
mj_sensorVel(m, d);
|
||||||
mj_energyVel(m, d);
|
mj_energyVel(m, d);
|
||||||
|
|
||||||
// if we had a callback we would be using mj_step, but call it anyway
|
// if we had a callback we would be using mj_step, but call it anyway
|
||||||
if( mjcb_control )
|
if( mjcb_control )
|
||||||
mjcb_control(m, d);
|
mjcb_control(m, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mj_step2(const mjModel* m, mjData* d)
|
void mj_step2(const mjModel* m, mjData* d)
|
||||||
{
|
{
|
||||||
mj_fwdActuation(m, d);
|
mj_fwdActuation(m, d);
|
||||||
mj_fwdAcceleration(m, d);
|
mj_fwdAcceleration(m, d);
|
||||||
mj_fwdConstraint(m, d);
|
mj_fwdConstraint(m, d);
|
||||||
mj_sensorAcc(m, d);
|
mj_sensorAcc(m, d);
|
||||||
mj_checkAcc(m, d);
|
mj_checkAcc(m, d);
|
||||||
|
|
||||||
// compare forward and inverse solutions if enabled
|
// compare forward and inverse solutions if enabled
|
||||||
if( mjENABLED(mjENBL_FWDINV) )
|
if( mjENABLED(mjENBL_FWDINV) )
|
||||||
mj_compareFwdInv(m, d);
|
mj_compareFwdInv(m, d);
|
||||||
|
|
||||||
// integrate with Euler; ignore integrator option
|
// integrate with Euler; ignore integrator option
|
||||||
mj_Euler(m, d);
|
mj_Euler(m, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
.. _siStateControl:
|
.. _siStateControl:
|
||||||
@@ -830,37 +856,35 @@ skip arguments (mjSTAGE_NONE, 0), where the latter function is implemented as
|
|||||||
|
|
||||||
.. code-block:: C
|
.. code-block:: C
|
||||||
|
|
||||||
void mj_forwardSkip(const mjModel* m, mjData* d,
|
void mj_forwardSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor) {
|
||||||
int skipstage, int skipsensor)
|
// position-dependent
|
||||||
{
|
if( skipstage<mjSTAGE_POS )
|
||||||
// position-dependent
|
{
|
||||||
if( skipstage<mjSTAGE_POS )
|
mj_fwdPosition(m, d);
|
||||||
{
|
|
||||||
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);
|
|
||||||
if( !skipsensor )
|
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
|
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
|
// parallel section
|
||||||
#pragma omp parallel
|
#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
|
// thread function
|
||||||
worker(m, d[n]); // shared mjModel (read-only), per-thread mjData (read-write)
|
worker(m, d[n]); // shared mjModel (read-only), per-thread mjData (read-write)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete per-thread mjData
|
// delete per-thread mjData
|
||||||
for( int n=0; n<nthread; n++ )
|
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
|
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.
|
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.
|
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
|
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
|
``testxml.cc`` and ``derivative.cc``, where we computed model mismatches after save and load, and assessed the accuracy
|
||||||
numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or simulation
|
of the numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or
|
||||||
paths that compute the same quantity, and compare the results numerically. This type of sanity check is essential when
|
simulation paths that compute the same quantity, and compare the results numerically. This type of sanity check is
|
||||||
dealing with complex dynamical systems where we do not really know what the numerical output should be; if we knew
|
essential when dealing with complex dynamical systems where we do not really know what the numerical output should be;
|
||||||
that, we would not be using a simulator in the first place.
|
if we knew that, we would not be using a simulator in the first place.
|
||||||
|
|
||||||
.. _siJacobian:
|
.. _siJacobian:
|
||||||
|
|
||||||
@@ -1529,29 +1553,28 @@ one of its derivatives.
|
|||||||
// ... install GLFW keyboard and mouse callbacks
|
// ... install GLFW keyboard and mouse callbacks
|
||||||
|
|
||||||
// run main loop, target real-time simulation and 60 fps rendering
|
// run main loop, target real-time simulation and 60 fps rendering
|
||||||
while( !glfwWindowShouldClose(window) )
|
while( !glfwWindowShouldClose(window) ) {
|
||||||
{
|
// advance interactive simulation for 1/60 sec
|
||||||
// advance interactive simulation for 1/60 sec
|
// Assuming MuJoCo can simulate faster than real-time, which it usually can,
|
||||||
// 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.
|
||||||
// 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.
|
||||||
// Otherwise add a cpu timer and exit this loop when it is time to render.
|
mjtNum simstart = d->time;
|
||||||
mjtNum simstart = d->time;
|
while( d->time - simstart < 1.0/60.0 )
|
||||||
while( d->time - simstart < 1.0/60.0 )
|
mj_step(m, d);
|
||||||
mj_step(m, d);
|
|
||||||
|
|
||||||
// get framebuffer viewport
|
// get framebuffer viewport
|
||||||
mjrRect viewport = {0, 0, 0, 0};
|
mjrRect viewport = {0, 0, 0, 0};
|
||||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||||
|
|
||||||
// update scene and render
|
// update scene and render
|
||||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||||
mjr_render(viewport, &scn, &con);
|
mjr_render(viewport, &scn, &con);
|
||||||
|
|
||||||
// swap OpenGL buffers (blocking call due to v-sync)
|
// swap OpenGL buffers (blocking call due to v-sync)
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|
||||||
// process pending GUI events, call GLFW callbacks
|
// process pending GUI events, call GLFW callbacks
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
// close GLFW, free visualization storage
|
// close GLFW, free visualization storage
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
Python Bindings
|
Python Bindings
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
Starting with version 2.1.2, MuJoCo comes with native Python bindings that are developed in C++ using
|
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
|
`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.
|
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==3.5.4
|
||||||
sphinx_rtd_theme==0.5.2
|
sphinx_rtd_theme==0.5.2
|
||||||
sphinxcontrib-katex==0.8.6
|
sphinxcontrib-katex==0.8.6
|
||||||
|
sphinxcontrib-youtube==1.1.0
|
||||||
sphinx-reredirects==0.0.1
|
sphinx-reredirects==0.0.1
|
||||||
nbsphinx==0.8.0
|
nbsphinx==0.8.0
|
||||||
pandoc==1.0.2
|
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
|
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
|
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``.
|
found by browsing the contents of ``MuJoCo.app``) and rename it as ``mujoco.dylib``.
|
||||||
|
|
||||||
Linux
|
Linux
|
||||||
_____
|
_____
|
||||||
|
|
||||||
Expand the ``tar.gz`` archive to ``~/.mujoco``. Then copy the dynamic library from
|
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
|
Windows
|
||||||
_______
|
_______
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
#ifndef MUJOCO_MJDATA_H_
|
#ifndef MUJOCO_MJDATA_H_
|
||||||
#define MUJOCO_MJDATA_H_
|
#define MUJOCO_MJDATA_H_
|
||||||
|
|
||||||
#include <mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||||
|
|
||||||
@@ -293,11 +293,11 @@ struct mjData_ {
|
|||||||
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||||
|
|
||||||
// computed by mj_fwdAcceleration
|
// computed by mj_fwdAcceleration
|
||||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
mjtNum* qfrc_smooth; // net unconstrained force (nv x 1)
|
||||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
mjtNum* qacc_smooth; // unconstrained acceleration (nv x 1)
|
||||||
|
|
||||||
// computed by mj_fwdConstraint/mj_inverse
|
// 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)
|
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#ifndef MUJOCO_MJMODEL_H_
|
#ifndef MUJOCO_MJMODEL_H_
|
||||||
#define MUJOCO_MJMODEL_H_
|
#define MUJOCO_MJMODEL_H_
|
||||||
|
|
||||||
#include <mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
|
|
||||||
// global constants
|
// global constants
|
||||||
#define mjPI 3.14159265358979323846
|
#define mjPI 3.14159265358979323846
|
||||||
@@ -68,9 +68,8 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags
|
|||||||
mjENBL_ENERGY = 1<<1, // energy computation
|
mjENBL_ENERGY = 1<<1, // energy computation
|
||||||
mjENBL_FWDINV = 1<<2, // record solver statistics
|
mjENBL_FWDINV = 1<<2, // record solver statistics
|
||||||
mjENBL_SENSORNOISE = 1<<3, // add noise to sensor data
|
mjENBL_SENSORNOISE = 1<<3, // add noise to sensor data
|
||||||
|
|
||||||
// experimental features:
|
// 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
|
mjNENABLE = 5 // number of enable flags
|
||||||
} mjtEnableBit;
|
} mjtEnableBit;
|
||||||
@@ -833,11 +832,13 @@ struct mjModel_ {
|
|||||||
int* actuator_group; // group for visibility (nu x 1)
|
int* actuator_group; // group for visibility (nu x 1)
|
||||||
mjtByte* actuator_ctrllimited; // is control limited (nu x 1)
|
mjtByte* actuator_ctrllimited; // is control limited (nu x 1)
|
||||||
mjtByte* actuator_forcelimited;// is force 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_dynprm; // dynamics parameters (nu x mjNDYN)
|
||||||
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
|
mjtNum* actuator_gainprm; // gain parameters (nu x mjNGAIN)
|
||||||
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
|
mjtNum* actuator_biasprm; // bias parameters (nu x mjNBIAS)
|
||||||
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
|
mjtNum* actuator_ctrlrange; // range of controls (nu x 2)
|
||||||
mjtNum* actuator_forcerange; // range of forces (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_gear; // scale length and transmitted force (nu x 6)
|
||||||
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
|
mjtNum* actuator_cranklength; // crank length for slider-crank (nu x 1)
|
||||||
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
|
mjtNum* actuator_acc0; // acceleration from unit force in qpos0 (nu x 1)
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#ifndef MUJOCO_MJRENDER_H_
|
#ifndef MUJOCO_MJRENDER_H_
|
||||||
#define MUJOCO_MJRENDER_H_
|
#define MUJOCO_MJRENDER_H_
|
||||||
|
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#ifndef MUJOCO_MJUI_H_
|
#ifndef MUJOCO_MJUI_H_
|
||||||
#define MUJOCO_MJUI_H_
|
#define MUJOCO_MJUI_H_
|
||||||
|
|
||||||
#include <mjrender.h>
|
#include <mujoco/mjrender.h>
|
||||||
|
|
||||||
#define mjMAXUISECT 10 // maximum number of sections
|
#define mjMAXUISECT 10 // maximum number of sections
|
||||||
#define mjMAXUIITEM 80 // maximum number of items per section
|
#define mjMAXUIITEM 80 // maximum number of items per section
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
#ifndef MUJOCO_MJVISUALIZE_H_
|
#ifndef MUJOCO_MJVISUALIZE_H_
|
||||||
#define MUJOCO_MJVISUALIZE_H_
|
#define MUJOCO_MJVISUALIZE_H_
|
||||||
|
|
||||||
#include <mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
|
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
|
||||||
#define mjMAXLIGHT 100 // maximum number of lights in a scene
|
#define mjMAXLIGHT 100 // maximum number of lights in a scene
|
||||||
@@ -20,28 +20,28 @@
|
|||||||
|
|
||||||
// scalar fields of mjOption
|
// scalar fields of mjOption
|
||||||
#define MJOPTION_FLOATS \
|
#define MJOPTION_FLOATS \
|
||||||
X( mjtNum, timestep ) \
|
X( mjtNum, timestep ) \
|
||||||
X( mjtNum, apirate ) \
|
X( mjtNum, apirate ) \
|
||||||
X( mjtNum, impratio ) \
|
X( mjtNum, impratio ) \
|
||||||
X( mjtNum, tolerance ) \
|
X( mjtNum, tolerance ) \
|
||||||
X( mjtNum, noslip_tolerance ) \
|
X( mjtNum, noslip_tolerance ) \
|
||||||
X( mjtNum, mpr_tolerance ) \
|
X( mjtNum, mpr_tolerance ) \
|
||||||
X( mjtNum, density ) \
|
X( mjtNum, density ) \
|
||||||
X( mjtNum, viscosity ) \
|
X( mjtNum, viscosity ) \
|
||||||
X( mjtNum, o_margin ) \
|
X( mjtNum, o_margin ) \
|
||||||
|
|
||||||
|
|
||||||
#define MJOPTION_INTS \
|
#define MJOPTION_INTS \
|
||||||
X( int, integrator ) \
|
X( int, integrator ) \
|
||||||
X( int, collision ) \
|
X( int, collision ) \
|
||||||
X( int, cone ) \
|
X( int, cone ) \
|
||||||
X( int, jacobian ) \
|
X( int, jacobian ) \
|
||||||
X( int, solver ) \
|
X( int, solver ) \
|
||||||
X( int, iterations ) \
|
X( int, iterations ) \
|
||||||
X( int, noslip_iterations ) \
|
X( int, noslip_iterations ) \
|
||||||
X( int, mpr_iterations ) \
|
X( int, mpr_iterations ) \
|
||||||
X( int, disableflags ) \
|
X( int, disableflags ) \
|
||||||
X( int, enableflags )
|
X( int, enableflags )
|
||||||
|
|
||||||
|
|
||||||
#define MJOPTION_SCALARS \
|
#define MJOPTION_SCALARS \
|
||||||
@@ -351,11 +351,13 @@
|
|||||||
X( int, actuator_group, nu, 1 ) \
|
X( int, actuator_group, nu, 1 ) \
|
||||||
X( mjtByte, actuator_ctrllimited, nu, 1 ) \
|
X( mjtByte, actuator_ctrllimited, nu, 1 ) \
|
||||||
X( mjtByte, actuator_forcelimited, nu, 1 ) \
|
X( mjtByte, actuator_forcelimited, nu, 1 ) \
|
||||||
|
X( mjtByte, actuator_actlimited, nu, 1 ) \
|
||||||
X( mjtNum, actuator_dynprm, nu, mjNDYN ) \
|
X( mjtNum, actuator_dynprm, nu, mjNDYN ) \
|
||||||
X( mjtNum, actuator_gainprm, nu, mjNGAIN ) \
|
X( mjtNum, actuator_gainprm, nu, mjNGAIN ) \
|
||||||
X( mjtNum, actuator_biasprm, nu, mjNBIAS ) \
|
X( mjtNum, actuator_biasprm, nu, mjNBIAS ) \
|
||||||
X( mjtNum, actuator_ctrlrange, nu, 2 ) \
|
X( mjtNum, actuator_ctrlrange, nu, 2 ) \
|
||||||
X( mjtNum, actuator_forcerange, nu, 2 ) \
|
X( mjtNum, actuator_forcerange, nu, 2 ) \
|
||||||
|
X( mjtNum, actuator_actrange, nu, 2 ) \
|
||||||
X( mjtNum, actuator_gear, nu, 6 ) \
|
X( mjtNum, actuator_gear, nu, 6 ) \
|
||||||
X( mjtNum, actuator_cranklength, nu, 1 ) \
|
X( mjtNum, actuator_cranklength, nu, 1 ) \
|
||||||
X( mjtNum, actuator_acc0, nu, 1 ) \
|
X( mjtNum, actuator_acc0, nu, 1 ) \
|
||||||
@@ -508,8 +510,8 @@
|
|||||||
X( mjtNum, subtree_angmom, nbody, 3 ) \
|
X( mjtNum, subtree_angmom, nbody, 3 ) \
|
||||||
X( mjtNum, actuator_force, nu, 1 ) \
|
X( mjtNum, actuator_force, nu, 1 ) \
|
||||||
X( mjtNum, qfrc_actuator, nv, 1 ) \
|
X( mjtNum, qfrc_actuator, nv, 1 ) \
|
||||||
X( mjtNum, qfrc_unc, nv, 1 ) \
|
X( mjtNum, qfrc_smooth, nv, 1 ) \
|
||||||
X( mjtNum, qacc_unc, nv, 1 ) \
|
X( mjtNum, qacc_smooth, nv, 1 ) \
|
||||||
X( mjtNum, efc_b, njmax, 1 ) \
|
X( mjtNum, efc_b, njmax, 1 ) \
|
||||||
X( mjtNum, efc_force, njmax, 1 ) \
|
X( mjtNum, efc_force, njmax, 1 ) \
|
||||||
X( int, efc_state, njmax, 1 ) \
|
X( int, efc_state, njmax, 1 ) \
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#ifndef MUJOCO_MUJOCO_H_
|
#ifndef MUJOCO_MUJOCO_H_
|
||||||
#define MUJOCO_MUJOCO_H_
|
#define MUJOCO_MUJOCO_H_
|
||||||
|
|
||||||
#include <mjexport.h>
|
#include <mujoco/mjexport.h>
|
||||||
|
|
||||||
|
|
||||||
// this is a C-API
|
// this is a C-API
|
||||||
@@ -24,7 +24,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// header version; should match the library version as returned by mj_version()
|
// 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
|
// needed to define size_t, fabs and log10
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
@@ -32,12 +32,12 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
// type definitions
|
// type definitions
|
||||||
#include <mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mjrender.h>
|
#include <mujoco/mjrender.h>
|
||||||
#include <mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mjui.h>
|
#include <mujoco/mjui.h>
|
||||||
#include <mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
|
|
||||||
|
|
||||||
// macros
|
// macros
|
||||||
@@ -139,12 +139,10 @@ MJAPI void mj_forward(const mjModel* m, mjData* d);
|
|||||||
MJAPI void mj_inverse(const mjModel* m, mjData* d);
|
MJAPI void mj_inverse(const mjModel* m, mjData* d);
|
||||||
|
|
||||||
// Forward dynamics with skip; skipstage is mjtStage.
|
// Forward dynamics with skip; skipstage is mjtStage.
|
||||||
MJAPI void mj_forwardSkip(const mjModel* m, mjData* d,
|
MJAPI void mj_forwardSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor);
|
||||||
int skipstage, int skipsensor);
|
|
||||||
|
|
||||||
// Inverse dynamics with skip; skipstage is mjtStage.
|
// Inverse dynamics with skip; skipstage is mjtStage.
|
||||||
MJAPI void mj_inverseSkip(const mjModel* m, mjData* d,
|
MJAPI void mj_inverseSkip(const mjModel* m, mjData* d, int skipstage, int skipsensor);
|
||||||
int skipstage, int skipsensor);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Initialization ------------------------------------------------
|
//---------------------------------- Initialization ------------------------------------------------
|
||||||
@@ -215,8 +213,7 @@ MJAPI int mj_setLengthRange(mjModel* m, mjData* d, int index,
|
|||||||
|
|
||||||
// Print mjModel to text file, specifying format.
|
// Print mjModel to text file, specifying format.
|
||||||
// float_format must be a valid printf-style format string for a single float value.
|
// 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,
|
MJAPI void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format);
|
||||||
const char* float_format);
|
|
||||||
|
|
||||||
// Print model to text file.
|
// Print model to text file.
|
||||||
MJAPI void mj_printModel(const mjModel* m, const char* filename);
|
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.
|
// Print sparse matrix to screen.
|
||||||
MJAPI void mju_printMatSparse(const mjtNum* mat, int nr,
|
MJAPI void mju_printMatSparse(const mjtNum* mat, int nr,
|
||||||
const int* rownnz, const int* rowadr,
|
const int* rownnz, const int* rowadr, const int* colind);
|
||||||
const int* colind);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Components ----------------------------------------------------
|
//---------------------------------- Components ----------------------------------------------------
|
||||||
@@ -246,7 +242,7 @@ MJAPI void mj_fwdPosition(const mjModel* m, mjData* d);
|
|||||||
// Run velocity-dependent computations.
|
// Run velocity-dependent computations.
|
||||||
MJAPI void mj_fwdVelocity(const mjModel* m, mjData* d);
|
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);
|
MJAPI void mj_fwdActuation(const mjModel* m, mjData* d);
|
||||||
|
|
||||||
// Add up all non-constraint forces, compute qacc_unc.
|
// 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);
|
MJAPI int mj_isDual(const mjModel* m);
|
||||||
|
|
||||||
// Multiply dense or sparse constraint Jacobian by vector.
|
// Multiply dense or sparse constraint Jacobian by vector.
|
||||||
MJAPI void mj_mulJacVec(const mjModel* m, mjData* d,
|
MJAPI void mj_mulJacVec(const mjModel* m, mjData* d, mjtNum* res, const mjtNum* vec);
|
||||||
mjtNum* res, const mjtNum* vec);
|
|
||||||
|
|
||||||
// Multiply dense or sparse constraint Jacobian transpose by vector.
|
// Multiply dense or sparse constraint Jacobian transpose by vector.
|
||||||
MJAPI void mj_mulJacTVec(const mjModel* m, mjData* d, mjtNum* res, const mjtNum* vec);
|
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.
|
// 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,
|
MJAPI void mj_jac(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr,
|
||||||
mjtNum* jacp, mjtNum* jacr, const mjtNum point[3], int body);
|
const mjtNum point[3], int body);
|
||||||
|
|
||||||
// Compute body frame end-effector Jacobian.
|
// Compute body frame end-effector Jacobian.
|
||||||
MJAPI void mj_jacBody(const mjModel* m, const mjData* d,
|
MJAPI void mj_jacBody(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int body);
|
||||||
mjtNum* jacp, mjtNum* jacr, int body);
|
|
||||||
|
|
||||||
// Compute body center-of-mass end-effector Jacobian.
|
// Compute body center-of-mass end-effector Jacobian.
|
||||||
MJAPI void mj_jacBodyCom(const mjModel* m, const mjData* d,
|
MJAPI void mj_jacBodyCom(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int body);
|
||||||
mjtNum* jacp, mjtNum* jacr, int body);
|
|
||||||
|
|
||||||
// Compute geom end-effector Jacobian.
|
// Compute geom end-effector Jacobian.
|
||||||
MJAPI void mj_jacGeom(const mjModel* m, const mjData* d,
|
MJAPI void mj_jacGeom(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int geom);
|
||||||
mjtNum* jacp, mjtNum* jacr, int geom);
|
|
||||||
|
|
||||||
// Compute site end-effector Jacobian.
|
// Compute site end-effector Jacobian.
|
||||||
MJAPI void mj_jacSite(const mjModel* m, const mjData* d,
|
MJAPI void mj_jacSite(const mjModel* m, const mjData* d, mjtNum* jacp, mjtNum* jacr, int site);
|
||||||
mjtNum* jacp, mjtNum* jacr, int site);
|
|
||||||
|
|
||||||
// Compute translation end-effector Jacobian of point, and rotation Jacobian of axis.
|
// Compute translation end-effector Jacobian of point, and rotation Jacobian of axis.
|
||||||
MJAPI void mj_jacPointAxis(const mjModel* m, mjData* d,
|
MJAPI void mj_jacPointAxis(const mjModel* m, mjData* d, mjtNum* jacPoint, mjtNum* jacAxis,
|
||||||
mjtNum* jacPoint, mjtNum* jacAxis,
|
|
||||||
const mjtNum point[3], const mjtNum axis[3], int body);
|
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.
|
// 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.
|
// Add inertia matrix to destination matrix.
|
||||||
// Destination can be sparse uncompressed, or dense when all int* are NULL
|
// Destination can be sparse uncompressed, or dense when all int* are NULL
|
||||||
MJAPI void mj_addM(const mjModel* m, mjData* d, mjtNum* dst,
|
MJAPI void mj_addM(const mjModel* m, mjData* d, mjtNum* dst, int* rownnz, int* rowadr, int* colind);
|
||||||
int* rownnz, int* rowadr, int* colind);
|
|
||||||
|
|
||||||
// Apply cartesian force and torque (outside xfrc_applied mechanism).
|
// Apply cartesian force and torque (outside xfrc_applied mechanism).
|
||||||
MJAPI void mj_applyFT(const mjModel* m, mjData* d,
|
MJAPI void mj_applyFT(const mjModel* m, mjData* d, const mjtNum force[3], const mjtNum torque[3],
|
||||||
const mjtNum force[3], const mjtNum torque[3],
|
|
||||||
const mjtNum point[3], int body, mjtNum* qfrc_target);
|
const mjtNum point[3], int body, mjtNum* qfrc_target);
|
||||||
|
|
||||||
// Compute object 6D velocity in object-centered frame, world/local orientation.
|
// 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);
|
MJAPI void mj_normalizeQuat(const mjModel* m, mjtNum* qpos);
|
||||||
|
|
||||||
// Map from body local to global Cartesian coordinates.
|
// Map from body local to global Cartesian coordinates.
|
||||||
MJAPI void mj_local2Global(mjData* d, mjtNum xpos[3], mjtNum xmat[9],
|
MJAPI void mj_local2Global(mjData* d, mjtNum xpos[3], mjtNum xmat[9], const mjtNum pos[3],
|
||||||
const mjtNum pos[3], const mjtNum quat[4],
|
const mjtNum quat[4], int body, mjtByte sameframe);
|
||||||
int body, mjtByte sameframe);
|
|
||||||
|
|
||||||
// Sum all body masses.
|
// Sum all body masses.
|
||||||
MJAPI mjtNum mj_getTotalmass(const mjModel* m);
|
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);
|
MJAPI void mjr_setAux(int index, const mjrContext* con);
|
||||||
|
|
||||||
// Blit from Aux buffer to con->currentBuffer.
|
// Blit from Aux buffer to con->currentBuffer.
|
||||||
MJAPI void mjr_blitAux(int index, mjrRect src, int left, int bottom,
|
MJAPI void mjr_blitAux(int index, mjrRect src, int left, int bottom, const mjrContext* con);
|
||||||
const mjrContext* con);
|
|
||||||
|
|
||||||
// Draw text at (x,y) in relative coordinates; font is mjtFont.
|
// Draw text at (x,y) in relative coordinates; font is mjtFont.
|
||||||
MJAPI void mjr_text(int font, const char* txt, const mjrContext* con,
|
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);
|
MJAPI mjtNum mju_dot(const mjtNum* vec1, const mjtNum* vec2, const int n);
|
||||||
|
|
||||||
// Multiply matrix and vector: res = mat * vec.
|
// Multiply matrix and vector: res = mat * vec.
|
||||||
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec,
|
MJAPI void mju_mulMatVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||||
int nr, int nc);
|
|
||||||
|
|
||||||
// Multiply transposed matrix and vector: res = mat' * vec.
|
// Multiply transposed matrix and vector: res = mat' * vec.
|
||||||
MJAPI void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec,
|
MJAPI void mju_mulMatTVec(mjtNum* res, const mjtNum* mat, const mjtNum* vec, int nr, int nc);
|
||||||
int nr, int nc);
|
|
||||||
|
|
||||||
// Transpose matrix: res = mat'.
|
// Transpose matrix: res = mat'.
|
||||||
MJAPI void mju_transpose(mjtNum* res, const mjtNum* mat, int nr, int nc);
|
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.
|
// Conjugate quaternion, corresponding to opposite rotation.
|
||||||
MJAPI void mju_negQuat(mjtNum res[4], const mjtNum quat[4]);
|
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]);
|
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]);
|
MJAPI void mju_mulQuatAxis(mjtNum res[4], const mjtNum quat[4], const mjtNum axis[3]);
|
||||||
|
|
||||||
// Convert axisAngle to quaternion.
|
// 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]);
|
MJAPI mjtNum mju_muscleDynamics(mjtNum ctrl, mjtNum act, const mjtNum prm[2]);
|
||||||
|
|
||||||
// Convert contact force to pyramid representation.
|
// Convert contact force to pyramid representation.
|
||||||
MJAPI void mju_encodePyramid(mjtNum* pyramid, const mjtNum* force,
|
MJAPI void mju_encodePyramid(mjtNum* pyramid, const mjtNum* force, const mjtNum* mu, int dim);
|
||||||
const mjtNum* mu, int dim);
|
|
||||||
|
|
||||||
// Convert pyramid representation to contact force.
|
// Convert pyramid representation to contact force.
|
||||||
MJAPI void mju_decodePyramid(mjtNum* force, const mjtNum* pyramid,
|
MJAPI void mju_decodePyramid(mjtNum* force, const mjtNum* pyramid, const mjtNum* mu, int dim);
|
||||||
const mjtNum* mu, int dim);
|
|
||||||
|
|
||||||
// Integrate spring-damper analytically, return pos(dt).
|
// Integrate spring-damper analytically, return pos(dt).
|
||||||
MJAPI mjtNum mju_springDamper(mjtNum pos0, mjtNum vel0, mjtNum Kp, mjtNum Kv, mjtNum 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_ENERGY', 2),
|
||||||
('mjENBL_FWDINV', 4),
|
('mjENBL_FWDINV', 4),
|
||||||
('mjENBL_SENSORNOISE', 8),
|
('mjENBL_SENSORNOISE', 8),
|
||||||
('mjENBL_MULTICCD', 1073741824),
|
('mjENBL_MULTICCD', 16),
|
||||||
('mjNENABLE', 5),
|
('mjNENABLE', 5),
|
||||||
]),
|
]),
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class EnumsTest(absltest.TestCase):
|
|||||||
('mjENBL_ENERGY', 1<<1),
|
('mjENBL_ENERGY', 1<<1),
|
||||||
('mjENBL_FWDINV', 1<<2),
|
('mjENBL_FWDINV', 1<<2),
|
||||||
('mjENBL_SENSORNOISE', 1<<3),
|
('mjENBL_SENSORNOISE', 1<<3),
|
||||||
('mjENBL_MULTICCD', 1<<30),
|
('mjENBL_MULTICCD', 1<<4),
|
||||||
('mjNENABLE', 5)))
|
('mjNENABLE', 5)))
|
||||||
|
|
||||||
# values mostly increment by one with occasional overrides
|
# 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',
|
('mj_fwdAcceleration',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -5895,7 +5895,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Muiltiply quaternions.',
|
doc='Multiply quaternions.',
|
||||||
)),
|
)),
|
||||||
('mju_mulQuatAxis',
|
('mju_mulQuatAxis',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -5924,7 +5924,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Muiltiply quaternion and axis.',
|
doc='Multiply quaternion and axis.',
|
||||||
)),
|
)),
|
||||||
('mju_axisAngle2Quat',
|
('mju_axisAngle2Quat',
|
||||||
FunctionDecl(
|
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
|
### 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
|
```bash
|
||||||
git clone https://github.com/deepmind/mujoco.git
|
git clone https://github.com/deepmind/mujoco.git
|
||||||
cd mujoco/python
|
cd mujoco/python
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create a virtual environment:
|
1. Create a virtual environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m venv /tmp/mujoco
|
python3 -m venv /tmp/mujoco
|
||||||
source /tmp/mujoco/bin/activate
|
source /tmp/mujoco/bin/activate
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Generate a [source distribution](https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist)
|
1. Generate a [source distribution](https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist)
|
||||||
tarball with the `make_sdist.sh` script.
|
tarball with the `make_sdist.sh` script.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd python
|
cd python
|
||||||
bash make_sdist.sh
|
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
|
**Note**: For macOS, this can be the path to a directory that contains the
|
||||||
cd dist
|
`mujoco.framework`. In particular, you can set
|
||||||
MUJOCO_PATH=/PATH/TO/MUJOCO pip install mujoco-2.1.X.tar.gz
|
`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
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -40,32 +40,60 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
|||||||
separate_arguments(CMDLINE_LINK_OPTIONS UNIX_COMMAND ${CMAKE_SHARED_LINKER_FLAGS})
|
separate_arguments(CMDLINE_LINK_OPTIONS UNIX_COMMAND ${CMAKE_SHARED_LINKER_FLAGS})
|
||||||
add_link_options(${CMDLINE_LINK_OPTIONS})
|
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)
|
include(MujocoLinkOptions)
|
||||||
get_mujoco_extra_link_options(EXTRA_LINK_OPTIONS)
|
get_mujoco_extra_link_options(EXTRA_LINK_OPTIONS)
|
||||||
add_link_options(${EXTRA_LINK_OPTIONS})
|
add_link_options(${EXTRA_LINK_OPTIONS})
|
||||||
|
|
||||||
if(APPLE)
|
include(MujocoMacOS)
|
||||||
add_compile_options(-Werror=partial-availability -Werror=unguarded-availability)
|
enforce_mujoco_macosx_min_version()
|
||||||
add_link_options(-Wl,-no_weak_imports)
|
|
||||||
|
if(WIN32)
|
||||||
|
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(MujocoHarden)
|
||||||
|
add_compile_options("${MUJOCO_HARDEN_COMPILE_OPTIONS}")
|
||||||
|
add_link_options("${MUJOCO_HARDEN_LINK_OPTIONS}")
|
||||||
|
|
||||||
find_package(Python3 COMPONENTS Interpreter Development)
|
find_package(Python3 COMPONENTS Interpreter Development)
|
||||||
|
|
||||||
include(FindOrFetch)
|
include(FindOrFetch)
|
||||||
|
|
||||||
# ==================== MUJOCO LIBRARY ==========================================
|
# ==================== MUJOCO LIBRARY ==========================================
|
||||||
if(NOT TARGET mujoco)
|
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)
|
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)
|
if(WIN32)
|
||||||
set_target_properties(mujoco PROPERTIES IMPORTED_IMPLIB "${MUJOCO_LIBRARY}")
|
set_target_properties(mujoco PROPERTIES IMPORTED_IMPLIB "${MUJOCO_LIBRARY}")
|
||||||
else()
|
else()
|
||||||
set_target_properties(mujoco PROPERTIES IMPORTED_LOCATION "${MUJOCO_LIBRARY}")
|
set_target_properties(mujoco PROPERTIES IMPORTED_LOCATION "${MUJOCO_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(mujoco INTERFACE "${MUJOCO_INCLUDE}")
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND otool -XD ${MUJOCO_LIBRARY}
|
COMMAND otool -XD ${MUJOCO_LIBRARY}
|
||||||
@@ -88,18 +116,7 @@ if(NOT TARGET mujoco)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ==================== ABSEIL ==================================================
|
# ==================== ABSEIL ==================================================
|
||||||
if(APPLE)
|
set(MUJOCO_PYTHON_ABSL_TARGETS absl::core_headers absl::flat_hash_map absl::span)
|
||||||
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()
|
|
||||||
findorfetch(
|
findorfetch(
|
||||||
USE_SYSTEM_PACKAGE
|
USE_SYSTEM_PACKAGE
|
||||||
OFF
|
OFF
|
||||||
@@ -110,14 +127,26 @@ findorfetch(
|
|||||||
GIT_REPO
|
GIT_REPO
|
||||||
https://github.com/abseil/abseil-cpp
|
https://github.com/abseil/abseil-cpp
|
||||||
GIT_TAG
|
GIT_TAG
|
||||||
215105818dfde3174fe799600bb0f3cae233d0bf # 20211102.0
|
78f9680225b9792c26dfdd99d0bd26c96de53dd4 # # Fixes universal builds for macOS
|
||||||
TARGETS
|
TARGETS
|
||||||
absl::core_headers
|
${MUJOCO_PYTHON_ABSL_TARGETS}
|
||||||
absl::flat_hash_map
|
|
||||||
absl::span
|
|
||||||
${ABSL_EXTRA_FETCH_ARGS}
|
|
||||||
EXCLUDE_FROM_ALL
|
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 ===================================================
|
# ==================== EIGEN ===================================================
|
||||||
add_compile_definitions(EIGEN_MPL2_ONLY)
|
add_compile_definitions(EIGEN_MPL2_ONLY)
|
||||||
@@ -138,26 +167,21 @@ findorfetch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# ==================== PYBIND11 ================================================
|
# ==================== PYBIND11 ================================================
|
||||||
if(MUJOCO_PYBIND11_DIR)
|
findorfetch(
|
||||||
FetchContent_Declare(pybind11 SOURCE_DIR ${MUJOCO_PYBIND11_DIR} EXCLUDE_FROM_ALL)
|
USE_SYSTEM_PACKAGE
|
||||||
FetchContent_MakeAvailable(pybind11)
|
OFF
|
||||||
else()
|
PACKAGE_NAME
|
||||||
findorfetch(
|
pybind11
|
||||||
USE_SYSTEM_PACKAGE
|
LIBRARY_NAME
|
||||||
OFF
|
pybind11
|
||||||
PACKAGE_NAME
|
GIT_REPO
|
||||||
pybind11
|
https://github.com/pybind/pybind11
|
||||||
LIBRARY_NAME
|
GIT_TAG
|
||||||
pybind11
|
a8f1a5567608f346bdba293b3d062a288ee16cd4
|
||||||
GIT_REPO
|
TARGETS
|
||||||
https://github.com/pybind/pybind11
|
pybind11::pybind11_headers
|
||||||
GIT_TAG
|
EXCLUDE_FROM_ALL
|
||||||
a8f1a5567608f346bdba293b3d062a288ee16cd4
|
)
|
||||||
TARGETS
|
|
||||||
pybind11::pybind11_headers
|
|
||||||
EXCLUDE_FROM_ALL
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ==================== MUJOCO PYTHON BINDINGS ==================================
|
# ==================== MUJOCO PYTHON BINDINGS ==================================
|
||||||
|
|
||||||
@@ -222,6 +246,7 @@ target_link_libraries(
|
|||||||
structs_header
|
structs_header
|
||||||
INTERFACE absl::flat_hash_map
|
INTERFACE absl::flat_hash_map
|
||||||
absl::span
|
absl::span
|
||||||
|
crossplatform
|
||||||
mujoco
|
mujoco
|
||||||
raw
|
raw
|
||||||
)
|
)
|
||||||
@@ -246,6 +271,19 @@ get_avx_compile_options(AVX_COMPILE_OPTIONS)
|
|||||||
macro(mujoco_pybind11_module name)
|
macro(mujoco_pybind11_module name)
|
||||||
pybind11_add_module(${name} ${ARGN})
|
pybind11_add_module(${name} ${ARGN})
|
||||||
target_compile_options(${name} PRIVATE ${AVX_COMPILE_OPTIONS})
|
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})
|
set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
@@ -323,6 +361,7 @@ mujoco_pybind11_module(
|
|||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
_structs
|
_structs
|
||||||
PRIVATE absl::flat_hash_map
|
PRIVATE absl::flat_hash_map
|
||||||
|
crossplatform
|
||||||
mujoco
|
mujoco
|
||||||
raw
|
raw
|
||||||
errors_header
|
errors_header
|
||||||
|
|||||||
@@ -53,6 +53,6 @@ if _MUJOCO_GL not in ('disable', 'disabled', 'off', 'false', '0'):
|
|||||||
else:
|
else:
|
||||||
from mujoco.glfw import GLContext
|
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
|
__version__ = mj_versionString() # pylint: disable=undefined-variable
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "raw.h"
|
#include "raw.h"
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ struct {enum.name} {{
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
namespace mujoco::python_traits {{
|
namespace mujoco::python_traits {{
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ struct {func.name} {{
|
|||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "util/crossplatform.h"
|
#include "util/crossplatform.h"
|
||||||
|
|
||||||
namespace mujoco::python_traits {{
|
namespace mujoco::python_traits {{
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include <pybind11/cast.h>
|
#include <pybind11/cast.h>
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <pybind11/stl.h>
|
|
||||||
|
|
||||||
namespace mujoco::python {
|
namespace mujoco::python {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -32,7 +32,7 @@ py::tuple MakeTuple(
|
|||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
result.append(py::str(strings[i]));
|
result.append(py::str(strings[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <auto N>
|
template <auto N>
|
||||||
@@ -44,7 +44,7 @@ py::tuple MakeTuple(const char* (&strings)[N][3]) {
|
|||||||
py::str(strings[i][1]),
|
py::str(strings[i][1]),
|
||||||
py::str(strings[i][2])));
|
py::str(strings[i][2])));
|
||||||
}
|
}
|
||||||
return result;
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_MODULE(_constants, pymodule) {
|
PYBIND11_MODULE(_constants, pymodule) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <mjexport.h>
|
#include <mujoco/mjexport.h>
|
||||||
#include "util/crossplatform.h"
|
#include "util/crossplatform.h"
|
||||||
#include "util/func_wrap.h"
|
#include "util/func_wrap.h"
|
||||||
#include <pybind11/pybind11.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::jmp_buf mju_error_jmp_buf;
|
||||||
static thread_local std::array<char, 1024> mju_error_msg{0};
|
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::strncpy(mju_error_msg.data(), msg, mju_error_msg.size());
|
||||||
std::longjmp(mju_error_jmp_buf, 1);
|
std::longjmp(mju_error_jmp_buf, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "util/array_traits.h"
|
#include "util/array_traits.h"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#ifndef MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
#ifndef MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
||||||
#define MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
#define MUJOCO_PYTHON_INDEXER_XMACRO_H_
|
||||||
|
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
|
|
||||||
#define MJMODEL_ACTUATOR \
|
#define MJMODEL_ACTUATOR \
|
||||||
X( int, actuator_, trntype, nu, 1 ) \
|
X( int, actuator_, trntype, nu, 1 ) \
|
||||||
@@ -26,11 +26,13 @@
|
|||||||
X( int, actuator_, group, nu, 1 ) \
|
X( int, actuator_, group, nu, 1 ) \
|
||||||
X( mjtByte, actuator_, ctrllimited, nu, 1 ) \
|
X( mjtByte, actuator_, ctrllimited, nu, 1 ) \
|
||||||
X( mjtByte, actuator_, forcelimited, nu, 1 ) \
|
X( mjtByte, actuator_, forcelimited, nu, 1 ) \
|
||||||
|
X( mjtByte, actuator_, actlimited, nu, 1 ) \
|
||||||
X( mjtNum, actuator_, dynprm, nu, mjNDYN ) \
|
X( mjtNum, actuator_, dynprm, nu, mjNDYN ) \
|
||||||
X( mjtNum, actuator_, gainprm, nu, mjNGAIN ) \
|
X( mjtNum, actuator_, gainprm, nu, mjNGAIN ) \
|
||||||
X( mjtNum, actuator_, biasprm, nu, mjNBIAS ) \
|
X( mjtNum, actuator_, biasprm, nu, mjNBIAS ) \
|
||||||
X( mjtNum, actuator_, ctrlrange, nu, 2 ) \
|
X( mjtNum, actuator_, ctrlrange, nu, 2 ) \
|
||||||
X( mjtNum, actuator_, forcerange, nu, 2 ) \
|
X( mjtNum, actuator_, forcerange, nu, 2 ) \
|
||||||
|
X( mjtNum, actuator_, actrange, nu, 2 ) \
|
||||||
X( mjtNum, actuator_, gear, nu, 6 ) \
|
X( mjtNum, actuator_, gear, nu, 6 ) \
|
||||||
X( mjtNum, actuator_, cranklength, nu, 1 ) \
|
X( mjtNum, actuator_, cranklength, nu, 1 ) \
|
||||||
X( mjtNum, actuator_, acc0, nu, 1 ) \
|
X( mjtNum, actuator_, acc0, nu, 1 ) \
|
||||||
@@ -361,8 +363,8 @@
|
|||||||
X( mjtNum, , qfrc_bias, nv, 1 ) \
|
X( mjtNum, , qfrc_bias, nv, 1 ) \
|
||||||
X( mjtNum, , qfrc_passive, nv, 1 ) \
|
X( mjtNum, , qfrc_passive, nv, 1 ) \
|
||||||
X( mjtNum, , qfrc_actuator, nv, 1 ) \
|
X( mjtNum, , qfrc_actuator, nv, 1 ) \
|
||||||
X( mjtNum, , qfrc_unc, nv, 1 ) \
|
X( mjtNum, , qfrc_smooth, nv, 1 ) \
|
||||||
X( mjtNum, , qacc_unc, nv, 1 ) \
|
X( mjtNum, , qacc_smooth, nv, 1 ) \
|
||||||
X( mjtNum, , qfrc_constraint, nv, 1 ) \
|
X( mjtNum, , qfrc_constraint, nv, 1 ) \
|
||||||
X( mjtNum, , qfrc_inverse, nv, 1 )
|
X( mjtNum, , qfrc_inverse, nv, 1 )
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,10 @@
|
|||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "errors.h"
|
|
||||||
#include "indexers.h"
|
#include "indexers.h"
|
||||||
#include "mjdata_meta.h"
|
#include "mjdata_meta.h"
|
||||||
#include "raw.h"
|
#include "raw.h"
|
||||||
#include <pybind11/pybind11.h>
|
#include "util/crossplatform.h"
|
||||||
|
|
||||||
namespace mujoco::python {
|
namespace mujoco::python {
|
||||||
|
|
||||||
@@ -218,13 +217,15 @@ MJDATA_VIEW_GROUPS
|
|||||||
#undef XGROUP
|
#undef XGROUP
|
||||||
|
|
||||||
#define MAKE_SHAPE(dim) \
|
#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")) { \
|
if constexpr (std::string_view(#dim) == std::string_view("1")) { \
|
||||||
return {}; \
|
return {}; \
|
||||||
} else { \
|
} else { \
|
||||||
return {n}; \
|
return {n}; \
|
||||||
} \
|
} \
|
||||||
}()
|
}() \
|
||||||
|
MUJOCO_DIAG_UNIGNORE_UNUSED_LAMBDA_CAPTURE
|
||||||
|
|
||||||
#undef MJ_M
|
#undef MJ_M
|
||||||
#define MJ_M(n) m_->n
|
#define MJ_M(n) m_->n
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <absl/container/flat_hash_map.h>
|
#include <absl/container/flat_hash_map.h>
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "indexer_xmacro.h"
|
#include "indexer_xmacro.h"
|
||||||
#include "mjdata_meta.h"
|
#include "mjdata_meta.h"
|
||||||
#include "raw.h"
|
#include "raw.h"
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
#ifndef MUJOCO_PYTHON_MJDATA_META_H_
|
#ifndef MUJOCO_PYTHON_MJDATA_META_H_
|
||||||
#define MUJOCO_PYTHON_MJDATA_META_H_
|
#define MUJOCO_PYTHON_MJDATA_META_H_
|
||||||
|
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "raw.h"
|
#include "raw.h"
|
||||||
|
#include "util/crossplatform.h"
|
||||||
|
|
||||||
namespace mujoco::python {
|
namespace mujoco::python {
|
||||||
namespace _impl {
|
namespace _impl {
|
||||||
@@ -95,7 +96,8 @@ struct MjDataMetadata {
|
|||||||
#undef X
|
#undef X
|
||||||
dummy_() {}
|
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
|
} // namespace mujoco::python
|
||||||
|
|||||||
+4
-4
@@ -15,10 +15,10 @@
|
|||||||
#ifndef MUJOCO_PYTHON_RAW_H_
|
#ifndef MUJOCO_PYTHON_RAW_H_
|
||||||
#define MUJOCO_PYTHON_RAW_H_
|
#define MUJOCO_PYTHON_RAW_H_
|
||||||
|
|
||||||
#include <mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
#include <mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mjrender.h>
|
#include <mujoco/mjrender.h>
|
||||||
#include <mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
|
|
||||||
// Type aliases for MuJoCo C structs to allow us refer to consistently refer
|
// Type aliases for MuJoCo C structs to allow us refer to consistently refer
|
||||||
// to them under the "raw" namespace.
|
// to them under the "raw" namespace.
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
#include <mjrender.h>
|
#include <mujoco/mjrender.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "function_traits.h"
|
#include "function_traits.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
|
|
||||||
namespace mujoco::python::_impl {
|
namespace mujoco::python::_impl {
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <absl/container/flat_hash_map.h>
|
#include <absl/container/flat_hash_map.h>
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "function_traits.h"
|
#include "function_traits.h"
|
||||||
#include "indexers.h"
|
#include "indexers.h"
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <absl/types/span.h>
|
#include <absl/types/span.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "indexers.h"
|
#include "indexers.h"
|
||||||
#include "mjdata_meta.h"
|
#include "mjdata_meta.h"
|
||||||
#include "raw.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));
|
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
|
// 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.
|
# INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
|
||||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
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)
|
add_library(crossplatform INTERFACE)
|
||||||
target_sources(crossplatform INTERFACE crossplatform.h)
|
target_sources(crossplatform INTERFACE crossplatform.h)
|
||||||
set_target_properties(crossplatform PROPERTIES PUBLIC_HEADER crossplatform.h)
|
set_target_properties(crossplatform PROPERTIES PUBLIC_HEADER crossplatform.h)
|
||||||
@@ -62,7 +57,8 @@ target_link_libraries(
|
|||||||
func_traits
|
func_traits
|
||||||
)
|
)
|
||||||
|
|
||||||
if(MUJOCO_TEST_PYTHON_UTIL)
|
if(BUILD_TESTING)
|
||||||
|
enable_testing()
|
||||||
add_executable(array_traits_test array_traits_test.cc)
|
add_executable(array_traits_test array_traits_test.cc)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
array_traits_test
|
array_traits_test
|
||||||
|
|||||||
@@ -48,4 +48,29 @@
|
|||||||
#define MUJOCO_ALWAYS_INLINE_LAMBDA_MUTABLE
|
#define MUJOCO_ALWAYS_INLINE_LAMBDA_MUTABLE
|
||||||
#endif
|
#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_
|
#endif // MUJOCO_PYTHON_UTIL_CROSSPLATFORM_H_
|
||||||
|
|||||||
+34
-18
@@ -30,7 +30,7 @@ from setuptools import find_packages
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from setuptools.command import build_ext
|
from setuptools.command import build_ext
|
||||||
|
|
||||||
__version__ = '2.1.5'
|
__version__ = '2.2.0'
|
||||||
|
|
||||||
MUJOCO_CMAKE = 'MUJOCO_CMAKE'
|
MUJOCO_CMAKE = 'MUJOCO_CMAKE'
|
||||||
MUJOCO_CMAKE_ARGS = 'MUJOCO_CMAKE_ARGS'
|
MUJOCO_CMAKE_ARGS = 'MUJOCO_CMAKE_ARGS'
|
||||||
@@ -137,7 +137,10 @@ class BuildCMakeExtension(build_ext.build_ext):
|
|||||||
"""Uses CMake to build extensions."""
|
"""Uses CMake to build extensions."""
|
||||||
|
|
||||||
def run(self):
|
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()
|
self._configure_cmake()
|
||||||
for ext in self.extensions:
|
for ext in self.extensions:
|
||||||
assert ext.name.startswith(EXT_PREFIX)
|
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')
|
raise RuntimeError(f'{MUJOCO_PATH} environment variable is not set')
|
||||||
library_path = None
|
library_path = None
|
||||||
include_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()):
|
if fnmatch.filter(filenames, get_mujoco_lib_pattern()):
|
||||||
library_path = directory
|
library_path = directory
|
||||||
if fnmatch.filter(filenames, 'mujoco.h'):
|
if os.path.exists(os.path.join(directory, 'mujoco/mujoco.h')):
|
||||||
include_path = directory
|
include_path = directory
|
||||||
if library_path and include_path:
|
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')
|
raise RuntimeError('Cannot find MuJoCo library and/or include paths')
|
||||||
|
|
||||||
def _copy_external_libraries(self):
|
def _copy_external_libraries(self):
|
||||||
@@ -171,8 +178,8 @@ class BuildCMakeExtension(build_ext.build_ext):
|
|||||||
def _copy_mujoco_headers(self):
|
def _copy_mujoco_headers(self):
|
||||||
dst = os.path.join(
|
dst = os.path.join(
|
||||||
os.path.dirname(self.get_ext_fullpath(self.extensions[0].name)),
|
os.path.dirname(self.get_ext_fullpath(self.extensions[0].name)),
|
||||||
'include')
|
'include/mujoco')
|
||||||
os.mkdir(dst)
|
os.makedirs(dst)
|
||||||
for directory, _, filenames in os.walk(self._mujoco_include_path):
|
for directory, _, filenames in os.walk(self._mujoco_include_path):
|
||||||
for filename in fnmatch.filter(filenames, '*.h'):
|
for filename in fnmatch.filter(filenames, '*.h'):
|
||||||
shutil.copyfile(os.path.join(directory, filename),
|
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'
|
build_cfg = 'Debug' if self.debug else 'Release'
|
||||||
cmake_module_path = os.path.join(os.path.dirname(__file__), 'cmake')
|
cmake_module_path = os.path.join(os.path.dirname(__file__), 'cmake')
|
||||||
cmake_args = [
|
cmake_args = [
|
||||||
f'-DPython3_ROOT_DIR={sys.prefix}',
|
f'-DPython3_ROOT_DIR:PATH={sys.prefix}',
|
||||||
f'-DPython3_EXECUTABLE={sys.executable}',
|
f'-DPython3_EXECUTABLE:STRING={sys.executable}',
|
||||||
f'-DMUJOCO_LIBRARY_DIR={self._mujoco_library_path}',
|
f'-DCMAKE_MODULE_PATH:PATH={cmake_module_path}',
|
||||||
f'-DMUJOCO_INCLUDE_DIR={self._mujoco_include_path}',
|
f'-DCMAKE_BUILD_TYPE:STRING={build_cfg}',
|
||||||
f'-DCMAKE_MODULE_PATH={cmake_module_path}',
|
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH={self.build_temp}',
|
||||||
f'-DCMAKE_BUILD_TYPE={build_cfg}',
|
f'-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=:BOOL{"OFF" if self.debug else "ON"}',
|
||||||
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={self.build_temp}',
|
|
||||||
f'-DCMAKE_INTERPROCEDURAL_OPTIMIZATION={"OFF" if self.debug else "ON"}',
|
|
||||||
'-DCMAKE_Fortran_COMPILER:STRING=',
|
'-DCMAKE_Fortran_COMPILER:STRING=',
|
||||||
'-DCMAKE_VERBOSE_MAKEFILE=ON',
|
'-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON',
|
||||||
'-DBUILD_TESTING=OFF',
|
'-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':
|
if platform.system() != 'Windows':
|
||||||
cmake_args.extend([
|
cmake_args.extend([
|
||||||
f'-DPython3_LIBRARY={sysconfig.get_paths()["stdlib"]}',
|
f'-DPython3_LIBRARY={sysconfig.get_paths()["stdlib"]}',
|
||||||
@@ -293,7 +309,7 @@ setup(
|
|||||||
'libmujoco.*.dylib',
|
'libmujoco.*.dylib',
|
||||||
'libmujoco*.so.*',
|
'libmujoco*.so.*',
|
||||||
'mujoco.dll',
|
'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.
|
# which is commonly available through your distro's package manager.
|
||||||
# On Debian and Ubuntu, GLFW can be installed via `apt install libglfw3-dev`.
|
# 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:
|
all:
|
||||||
$(CXX) $(COMMON) testxml.cc -lmujoco -o ../bin/testxml
|
$(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
|
# This Makefile assumes that GLFW is installed via Homebrew.
|
||||||
# packages are installed in /usr/local. If your setup is different, you will
|
# If your setup is different, you will need to set GLFWROOT manually.
|
||||||
# need to adjust the HOMEBREW variable accordingly.
|
|
||||||
|
|
||||||
# This Makefile also assumes that MuJoCo.app is present in /Applications.
|
# 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
|
CFLAGS=-O2 -F$(MUJOCOPATH) -I$(GLFWROOT)/include -pthread
|
||||||
MUJOCO_INCLUDEDIR=/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.Framework/Versions/A/Headers
|
CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++
|
||||||
CFLAGS=-O2 -I$(MUJOCO_INCLUDEDIR) -I$(HOMEBREW)/include -pthread
|
ALLFLAGS=$(CXXFLAGS) -L$(GLFWROOT)/lib -Wl,-rpath,$(MUJOCOPATH)
|
||||||
ALLFLAGS=$(CFLAGS) -L$(MUJOCO_LIBDIR) -L$(HOMEBREW)/lib -std=c++11 -stdlib=libc++ -Wl,-rpath,/Applications/MuJoCo.app/Contents/Frameworks
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
clang++ $(ALLFLAGS) testxml.cc -lmujoco.2.1.5 -o testxml
|
clang++ $(ALLFLAGS) testxml.cc -framework mujoco -o testxml
|
||||||
clang++ $(ALLFLAGS) testspeed.cc -lmujoco.2.1.5 -o testspeed
|
clang++ $(ALLFLAGS) testspeed.cc -framework mujoco -o testspeed
|
||||||
clang++ $(ALLFLAGS) compile.cc -lmujoco.2.1.5 -o compile
|
clang++ $(ALLFLAGS) compile.cc -framework mujoco -o compile
|
||||||
clang++ $(ALLFLAGS) derivative.cc -lmujoco.2.1.5 -o derivative
|
clang++ $(ALLFLAGS) derivative.cc -framework mujoco -o derivative
|
||||||
clang++ $(ALLFLAGS) basic.cc -lmujoco.2.1.5 -lglfw -o basic
|
clang++ $(ALLFLAGS) basic.cc -framework mujoco -lglfw -o basic
|
||||||
clang++ $(ALLFLAGS) record.cc -lmujoco.2.1.5 -lglfw -o record
|
clang++ $(ALLFLAGS) record.cc -framework mujoco -lglfw -o record
|
||||||
clang -c $(CFLAGS) uitools.c
|
clang -c $(CFLAGS) uitools.c
|
||||||
clang++ $(ALLFLAGS) uitools.o simulate.cc -lmujoco.2.1.5 -lglfw -o simulate
|
clang++ -c $(CXXFLAGS) macos_save.mm
|
||||||
|
clang++ $(ALLFLAGS) simulate.cc uitools.o macos_save.o -framework mujoco -framework Cocoa -lglfw -o simulate
|
||||||
rm *.o
|
rm *.o
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "GLFW/glfw3.h"
|
#include <GLFW/glfw3.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
// MuJoCo data structures
|
// MuJoCo data structures
|
||||||
mjModel* m = NULL; // MuJoCo model
|
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 <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
// help
|
// help
|
||||||
const char helpstring[] =
|
const char helpstring[] =
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
// enable compilation with and without OpenMP support
|
// enable compilation with and without OpenMP support
|
||||||
#if defined(_OPENMP)
|
#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 <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
// select EGL, OSMESA or GLFW
|
// select EGL, OSMESA or GLFW
|
||||||
#if defined(MJ_EGL)
|
#if defined(MJ_EGL)
|
||||||
|
|||||||
+27
-4
@@ -19,7 +19,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "uitools.h"
|
#include "uitools.h"
|
||||||
|
|
||||||
#include "array_safety.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
|
// handle UI event
|
||||||
void uiEvent(mjuiState* state) {
|
void uiEvent(mjuiState* state) {
|
||||||
int i;
|
int i;
|
||||||
@@ -1305,13 +1320,21 @@ void uiEvent(mjuiState* state) {
|
|||||||
if (it && it->sectionid==SECT_FILE) {
|
if (it && it->sectionid==SECT_FILE) {
|
||||||
switch (it->itemid) {
|
switch (it->itemid) {
|
||||||
case 0: // Save xml
|
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;
|
break;
|
||||||
|
|
||||||
case 1: // Save mjb
|
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;
|
break;
|
||||||
|
|
||||||
case 2: // Print model
|
case 2: // Print model
|
||||||
|
|||||||
+3
-2
@@ -18,7 +18,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
|
|
||||||
// maximum number of threads
|
// maximum number of threads
|
||||||
@@ -94,7 +94,8 @@ void simulate(int id, int nstep, mjtNum ctrlnoise) {
|
|||||||
|
|
||||||
|
|
||||||
// main function
|
// main function
|
||||||
int main(int argc, const char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
// print help if arguments are missing
|
// print help if arguments are missing
|
||||||
if (argc<2 || argc>6) {
|
if (argc<2 || argc>6) {
|
||||||
return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
|
return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
#include "array_safety.h"
|
#include "array_safety.h"
|
||||||
namespace mju = ::mujoco::sample_util;
|
namespace mju = ::mujoco::sample_util;
|
||||||
|
|||||||
+2
-2
@@ -16,8 +16,8 @@
|
|||||||
#define MUJOCO_UITOOLS_H_
|
#define MUJOCO_UITOOLS_H_
|
||||||
|
|
||||||
|
|
||||||
#include "GLFW/glfw3.h"
|
#include <GLFW/glfw3.h>
|
||||||
#include <mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
// this is a C-API
|
// this is a C-API
|
||||||
#if defined(__cplusplus)
|
#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