Skip to content

Commit

Permalink
[gym] Maintenance update. (#390)
Browse files Browse the repository at this point in the history
* [core] Fix random physics sampling.
* [core] Make sure random physics parameters are valid
* [python/simulator] Fix default external force display during replay.
* [python/viewer] Check that 'time_interval' is valid. Fix out-of-range edge case.
* [python/viewer] Fix support of robot without sensors nor freeflyer.
* [gym/common] More efficient random number generator.
* [gym/common] Fast space 'clip' utility.
* [gym/common] Reset internal '_info' buffer before calling 'is_done' to enable storing extra info. (#386)
* [gym/common] Do not automatically disable telemetry anymore.
* [gym/common] Enable 'refresh_observation' to access up-to-date shared internal data. (#384) 
* [gym/common] '_setup' updates frame kinematics for neutral configuration by default.
* [gym/common] Various minor bug fixes.
* [gym/toolbox] Add more convex hull utilities.
* [gym/toolbox] Add math utilities to extract yaw from transform.
* [gym/toolbox] Fix computation of distance from convex hull.
* [gym/rllib] Fix connection of existing ray cluster head.
* [gym/rllib] Clip random obs to space bounds in PPO regularization.
* [gym/rllib] Fix support of non-dict obs space for 'build_policy_wrapper'.
* [misc] Add mass fixed frame with visual to cartpole.
* [misc] Disable warnings when build SOUP. (#378)
* [misc] Fix push gym_jiminy wheels on pypi. (#379)
* [misc] Fix support of python virtual env for easy-install script. (#383)

Co-authored-by: Alexis Duburcq <alexis.duburcq@wandercraft.eu>
  • Loading branch information
duburcqa and Alexis Duburcq authored Aug 4, 2021
1 parent 305a11b commit 28449b9
Show file tree
Hide file tree
Showing 25 changed files with 386 additions and 168 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/manylinux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ jobs:
packages_dir: build/wheelhouse
- name: Publish on PyPi the wheel of Gym Jiminy (Any platform / Any python3 version)
if: >-
success() && matrix.container == 'manylinux2010_x86_64' && matrix.PYTHON_VERSION == '3.6' && matrix.legacy == false &&
success() && matrix.container == 'manylinux2010_x86_64' && matrix.PYTHON_VERSION == 'cp36' && matrix.legacy == false &&
github.repository == 'duburcqa/jiminy' && github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: pypa/gh-action-pypi-publish@master
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
echo "/home/runner/.local/bin" >> $GITHUB_PATH
- name: Installing requirements
run: |
sudo "${GITHUB_WORKSPACE}/build_tools/easy_install_deps_ubuntu.sh"
sudo env "PATH=$PATH" "${GITHUB_WORKSPACE}/build_tools/easy_install_deps_ubuntu.sh"
"${PYTHON_EXECUTABLE}" -m pip install --upgrade numpy
"${PYTHON_EXECUTABLE}" -m pip install tensorflow
"${PYTHON_EXECUTABLE}" -m pip install "torch==1.8.0+cpu" -f https://download.pytorch.org/whl/torch_stable.html
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.10)

# Set the build version
set(BUILD_VERSION 1.6.27)
set(BUILD_VERSION 1.6.28)

# Set compatibility
if(CMAKE_VERSION VERSION_GREATER "3.11.0")
Expand Down
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ python -m pip install gym-jiminy
First, one must install the pre-compiled libraries of the dependencies. Most of them are available on `robotpkg` APT repository. Just run the bash script to install them automatically for Ubuntu 18 and upward. It should be straightforward to adapt it to any other distribution for which `robotpkg` is available.

```bash
sudo ./build_tools/easy_install_deps_ubuntu.sh
sudo env "PATH=$PATH" ./build_tools/easy_install_deps_ubuntu.sh
```

You are now ready to build and install Jiminy itself.
Expand Down
4 changes: 2 additions & 2 deletions build_tools/cmake/setupPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endif()

# Get Python version
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import sys ; print(';'.join([str(x) for x in sys.version_info[:3]]), end='')"
"import sys ; print(';'.join(map(str, sys.version_info[:3])), end='')"
OUTPUT_VARIABLE _VERSION)
list(GET _VERSION 0 Python_VERSION_MAJOR)
list(GET _VERSION 1 Python_VERSION_MINOR)
Expand All @@ -43,7 +43,7 @@ endif()

# Get Python system and user site-packages
execute_process(COMMAND "${Python_EXECUTABLE}" -c
"import sysconfig; print(sysconfig.get_paths()['purelib'], end='')"
"import sysconfig; print(sysconfig.get_path('purelib'), end='')"
OUTPUT_VARIABLE Python_SYS_SITELIB)
message(STATUS "Python system site-packages: ${Python_SYS_SITELIB}")
execute_process(COMMAND "${Python_EXECUTABLE}" -m site --user-site
Expand Down
89 changes: 57 additions & 32 deletions build_tools/easy_install_deps_ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,61 @@

export DEBIAN_FRONTEND=noninteractive

# Make sure the script has root privilege
if ! [ $(id -u) = 0 ]; then
echo 'This script must be executed using `sudo env "PATH=$PATH"`.'
exit 1
fi

# Set SUDO_UID to 0 (root) if not defined, which may happen in docker container
if [ -z ${SUDO_UID+x} ]; then
SUDO_UID=0;
fi

# Determine if the script is being executed on Ubuntu
if [ -f /etc/lsb-release ]; then
source /etc/lsb-release
if [ "$DISTRIB_ID" != "Ubuntu" ] ; then
if [ "${DISTRIB_ID}" != "Ubuntu" ] ; then
echo "Not running on Ubuntu. Aborting..."
exit 0
exit 1
fi
else
echo "Not running on Ubuntu. Aborting..."
exit 0
exit 1
fi
echo "-- Linux distribution: ${DISTRIB_ID} ${DISTRIB_CODENAME}"

# Get Python 3 executable
PYTHON_BIN="$(basename $(readlink $(which python3)))"
# Check if current python executable has the same version as the built-in one
GET_PYTHON_VERSION="python3 -c \"import sys ; print('.'.join(map(str, sys.version_info[:2])), end='')\""
PYTHON_VERSION="$(eval ${GET_PYTHON_VERSION})"
PYTHON_SYS_VERSION="$(sudo -s eval ${GET_PYTHON_VERSION})"
if [ "${PYTHON_VERSION}" != "${PYTHON_SYS_VERSION}" ]; then
echo "Python version must match the built-in one if using a virtual env."
exit 1
fi
echo "-- Python executable: $(which python3)"
echo "-- Python version: ${PYTHON_VERSION}"

# Set SUDO_UID to 0 (root) if not defined, which may happen in docker container
if [ -z ${SUDO_UID+x} ]; then
SUDO_UID=0;
# Get Python 3 executable and wrtiable site packages location
PYTHON_BIN="python${PYTHON_VERSION}"
PYTHON_SITELIB="$(python3 -c "import sysconfig; print(sysconfig.get_path('purelib'), end='')")"
echo "-- Python default site-packages: ${PYTHON_SITELIB}"
if ! test -w "${PYTHON_SITELIB}" ; then
PYTHON_SITELIB="$(sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m site --user-site)"
fi
echo "-- Python writable site-packages: ${PYTHON_SITELIB}"

# Install Python 3 standard utilities
apt update && \
apt install -y sudo python3-setuptools python3-pip python3-tk && \
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade pip && \
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade wheel && \
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade "numpy>=1.16"
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade pip && \
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade wheel && \
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade "numpy>=1.16"

# Install Python 3 toolsuite for testing and documentation generation
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade setuptools auditwheel && \
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade flake8 pylint mypy types-toml && \
sudo -u $(id -nu "$SUDO_UID") env "PATH=$PATH" python3 -m pip install --upgrade \
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade setuptools auditwheel && \
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade flake8 pylint mypy types-toml && \
sudo -u $(id -nu "${SUDO_UID}") env "PATH=${PATH}" python3 -m pip install --upgrade \
pygments colorama sphinx sphinx_rtd_theme recommonmark nbsphinx breathe aafigure

# Install standard linux utilities
Expand All @@ -46,25 +70,26 @@ apt install -y libeigen3-dev libboost-all-dev liboctomap-dev
# Install OpenGL
apt install -y mesa-utils

# Install robotpkg tools suite
if ! [ -d "/opt/openrobots/lib/${PYTHON_BIN}/site-packages/" ] ; then
# Add apt repository if necessary
if ! grep -q "^deb .*robotpkg.openrobots.org" /etc/apt/sources.list.d/*; then
sh -c "echo 'deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub ${DISTRIB_CODENAME} robotpkg' >> /etc/apt/sources.list.d/robotpkg.list" && \
curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key | apt-key add - && \
apt update
fi
# Add robotpkg apt repository if necessary
if ! grep -q "^deb .*robotpkg.openrobots.org" /etc/apt/sources.list.d/*; then
sh -c "echo 'deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub ${DISTRIB_CODENAME} robotpkg' >> /etc/apt/sources.list.d/robotpkg.list" && \
curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key | apt-key add - && \
apt update
fi

# apt-get must be used instead of apt to support wildcard in package name on Ubuntu 20
apt-get install -y --allow-downgrades --allow-unauthenticated \
robotpkg-octomap=1.9.0 robotpkg-urdfdom-headers=1.0.4 robotpkg-hpp-fcl=1.7.1 robotpkg-pinocchio=2.5.6 \
robotpkg-qt5-osgqt=3.5.7r2 robotpkg-py3*-qt5-gepetto-viewer=4.12.0r2 robotpkg-py3*-qt5-gepetto-viewer-corba=5.6.0 \
robotpkg-py3*-omniorbpy=4.2.4 robotpkg-py3*-eigenpy=2.6.2 robotpkg-py3*-hpp-fcl=1.7.1 robotpkg-py3*-pinocchio=2.5.6
# Install robotpkg tools suite.
# Note that `apt-get` is used instead of `apt` because it supports wildcard in package names
apt-get install -y --allow-downgrades --allow-unauthenticated \
robotpkg-octomap=1.9.0 robotpkg-urdfdom-headers=1.0.4 robotpkg-hpp-fcl=1.7.1 robotpkg-pinocchio=2.5.6 \
robotpkg-qt5-osgqt=3.5.7r2 robotpkg-py3*-qt5-gepetto-viewer=4.12.0r2 robotpkg-py3*-qt5-gepetto-viewer-corba=5.6.0 \
robotpkg-py3*-omniorbpy=4.2.4 robotpkg-py3*-eigenpy=2.6.2 robotpkg-py3*-hpp-fcl=1.7.1 robotpkg-py3*-pinocchio=2.5.6

# Add openrobots libraries to python packages search path
if ! [ -f "${PYTHON_SITELIB}/openrobots.pth" ]; then
sudo -H -u $(id -nu "$SUDO_UID") bash -c " \
echo 'export LD_LIBRARY_PATH=\"/opt/openrobots/lib:\${LD_LIBRARY_PATH}\"' >> \$HOME/.bashrc && \
echo 'export PATH=\"\${PATH}:/opt/openrobots/bin\"' >> \$HOME/.bashrc && \
mkdir -p \$HOME/.local/lib/${PYTHON_BIN}/site-packages && \
touch \$HOME/.local/lib/${PYTHON_BIN}/site-packages/openrobots.pth && \
echo /opt/openrobots/lib/${PYTHON_BIN}/site-packages/ > \$HOME/.local/lib/${PYTHON_BIN}/site-packages/openrobots.pth"
echo 'export LD_LIBRARY_PATH=\"/opt/openrobots/lib:\${LD_LIBRARY_PATH}\"' >> \${HOME}/.bashrc && \
echo 'export PATH=\"\${PATH}:/opt/openrobots/bin\"' >> \${HOME}/.bashrc && \
mkdir -p '${PYTHON_SITELIB}' && \
touch '${PYTHON_SITELIB}/openrobots.pth' && \
echo '/opt/openrobots/lib/${PYTHON_BIN}/site-packages/' > '${PYTHON_SITELIB}/openrobots.pth'"
fi
2 changes: 1 addition & 1 deletion core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ else()
message(STATUS "Found urdfdom")
endif()
find_package(pinocchio 2.5.6 REQUIRED NO_MODULE NO_CMAKE_SYSTEM_PATH) # Pinocchio v2.5.6 fixes 'aba' overwritting 'data.a_gf'
find_package(hpp-fcl 1.5.4 REQUIRED NO_MODULE NO_CMAKE_SYSTEM_PATH) # hpp-fcl >= 1.5.4 adds support of collision of primitives with halfspace
find_package(hpp-fcl 1.7.1 REQUIRED NO_MODULE NO_CMAKE_SYSTEM_PATH) # hpp-fcl >= 1.7.1 adds collision geometry pointers
find_package(Eigen3 3.3.0 REQUIRED NO_MODULE) # It adds the target Eigen3::Eigen

# Pinocchio-specific stuffs
Expand Down
44 changes: 29 additions & 15 deletions core/src/robot/Model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ namespace jiminy
if (comBiasStd > EPS)
{
vector3_t & comRelativePositionBody = pncModel_.inertias[jointIdx].lever();
comRelativePositionBody.array() *= randVectorNormal(3U, comBiasStd).array();
comRelativePositionBody.array() *= 1.0 + randVectorNormal(3U, comBiasStd).array();
}

/* Add bias to body mass.
Expand Down Expand Up @@ -1132,7 +1132,7 @@ namespace jiminy
matrix3_t inertiaBodyAxes = solver.eigenvectors();
vector3_t const randAxis = randVectorNormal(3U, inertiaBiasStd);
inertiaBodyAxes = inertiaBodyAxes * quaternion_t(pinocchio::exp3(randAxis));
inertiaBodyMoments.array() *= randVectorNormal(3U, inertiaBiasStd).array();
inertiaBodyMoments.array() *= 1.0 + randVectorNormal(3U, inertiaBiasStd).array();
inertiaBody = pinocchio::Symmetric3((
inertiaBodyAxes * inertiaBodyMoments.asDiagonal() * inertiaBodyAxes.transpose()).eval());
}
Expand All @@ -1142,7 +1142,7 @@ namespace jiminy
if (relativeBodyPosBiasStd > EPS)
{
vector3_t & relativePositionBody = pncModel_.jointPlacements[jointIdx].translation();
relativePositionBody.array() *= randVectorNormal(3U, relativeBodyPosBiasStd).array();
relativePositionBody.array() *= 1.0 + randVectorNormal(3U, relativeBodyPosBiasStd).array();
}
}

Expand Down Expand Up @@ -1645,8 +1645,7 @@ namespace jiminy
}

// Check if the flexible model and its proxies must be regenerated
configHolder_t & dynOptionsHolder =
boost::get<configHolder_t>(modelOptions.at("dynamics"));
configHolder_t & dynOptionsHolder = boost::get<configHolder_t>(modelOptions.at("dynamics"));
bool_t const & enableFlexibleModel = boost::get<bool_t>(dynOptionsHolder.at("enableFlexibleModel"));
flexibilityConfig_t const & flexibilityConfig =
boost::get<flexibilityConfig_t>(dynOptionsHolder.at("flexibilityConfig"));
Expand All @@ -1663,20 +1662,35 @@ namespace jiminy
{
isCurrentModelInvalid = true;
}
}

// Check that the collisions options are valid
configHolder_t & collisionOptionsHolder = boost::get<configHolder_t>(modelOptions.at("collisions"));
uint32_t const & maxContactPointsPerBody = boost::get<uint32_t>(collisionOptionsHolder.at("maxContactPointsPerBody"));
if (maxContactPointsPerBody < 1)
{
PRINT_ERROR("The number of contact points by collision pair 'maxContactPointsPerBody' must be at least 1.");
return hresult_t::ERROR_BAD_INPUT;
}
if (mdlOptions_ && maxContactPointsPerBody != mdlOptions_->collisions.maxContactPointsPerBody)
{
isCollisionDataInvalid = true;
}

// Check that the collisions options are valid
configHolder_t & collisionOptionsHolder =
boost::get<configHolder_t>(modelOptions.at("collisions"));
uint32_t const & maxContactPointsPerBody = boost::get<uint32_t>(collisionOptionsHolder.at("maxContactPointsPerBody"));
if (maxContactPointsPerBody < 1)
// Check that the model randomization parameters are valid
configHolder_t & dynOptionsHolder = boost::get<configHolder_t>(modelOptions.at("dynamics"));
for (std::string const & field : std::vector<std::string>{
"inertiaBodiesBiasStd",
"massBodiesBiasStd",
"centerOfMassPositionBodiesBiasStd",
"relativePositionBodiesBiasStd"})
{
float64_t const & value = boost::get<float64_t>(dynOptionsHolder.at(field));
if (0.9 < value || value < 0.0)
{
PRINT_ERROR("The number of contact points by collision pair 'maxContactPointsPerBody' must be at least 1.");
PRINT_ERROR("'" + field + "' must be positive, and lower than 0.9 to avoid physics issues.");
return hresult_t::ERROR_BAD_INPUT;
}
if (mdlOptions_ && maxContactPointsPerBody != mdlOptions_->collisions.maxContactPointsPerBody)
{
isCollisionDataInvalid = true;
}
}

// Update the internal options
Expand Down
4 changes: 3 additions & 1 deletion core/src/utilities/Random.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ namespace jiminy
vectorN_t randVectorNormal(uint32_t const & size,
float64_t const & std)
{
return randVectorNormal(size, 0, std);
return randVectorNormal(size, 0.0, std);
}

vectorN_t randVectorNormal(vectorN_t const & mean,
Expand Down Expand Up @@ -736,6 +736,7 @@ namespace jiminy
void RandomPerlinProcess::initialize(void)
{
// Add desired perlin noise octaves
octaves_.clear();
octaves_.reserve(numOctaves_);
float64_t octaveWavelength = wavelength_;
float64_t octaveScale = 1.0;
Expand Down Expand Up @@ -764,6 +765,7 @@ namespace jiminy
void PeriodicPerlinProcess::initialize(void)
{
// Add desired perlin noise octaves
octaves_.clear();
octaves_.reserve(numOctaves_);
float64_t octaveWavelength = wavelength_;
float64_t octaveScale = 1.0;
Expand Down
15 changes: 15 additions & 0 deletions data/toys_models/cartpole/cartpole.urdf
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,19 @@
<inertia ixx="0.0" ixy="0.0" ixz="0.0" iyy="0.0" iyz="0.0" izz="0.0"/>
</inertial>
</link>
<joint name="pole_to_mass" type="fixed">
<origin xyz="0.0 0.0 1.0" rpy="0.0 0.0 0.0"/>
<parent link="pole"/>
<child link="mass"/>
</joint>
<link name="mass">
<visual>
<geometry>
<sphere radius="0.05"/>
</geometry>
<material name="white">
<color rgba="1.0 1.0 1.0 1.0"/>
</material>
</visual>
</link>
</robot>
Loading

0 comments on commit 28449b9

Please sign in to comment.