Skip to content

Commit

Permalink
Jiminy release 1.8.6 (#802)
Browse files Browse the repository at this point in the history
* [core] Make 'jiminy::Model' and 'jiminy::Robot' copyable. (#791)
* [core] Add stairs terrain (#797)
* [core] Define position, velocity and effort limits at motor level. (#798)
* [core] Implement velocity limits at motor-level. (#798)
* [core] Allow direct access to all motors / sensors attached to a robot. (#798)
* [core] Remove spring-damper position bounds dynamics to always use constraints. (#798)
* [core] Remove damper velocity bounds dynamics. (#798)
* [core] Define motor armature option at motor-side. (#798)
* [core] Remove dedicated robot attributes for position, velocity and effort limits. (#798)
* [core] Remove inefficient motor / sensor convenience helpers of 'Robot'. (#798)
* [core] Log total joint effort instead of confusing motor effort on joint side. (#798)
* [core] Enable attaching encoders either on motor or joint side. (#798)
* [core] Mechanical reduction is now fully supported. (#798)
* [core] Fix adding flexibility frame on root joint of fixed-base robot. (#798)
* [core] Move 'enable(Velocity|Effort)Limit' options from AbstractMotor to SimpleMotor. (#798)
* [core] Add velocity-torque slope when approaching maximum torque. (#798)
* [core] Keep track of motor efforts both on motor and joint sides. (#801)
* [core] Effort sensors now measure motor effort before transmission. (#801)
* [core|python] Various cleanup. (#790)
* [python] Introduce first-class trajectory object. (#790)
* [python/log] Fix trajectory and sensor data extraction and replay from log. (#800)
* [python/plot] Get around tabbed figure hanging for 'matplotlib>=3.8'. (#795)
* [python/viewer] Add missing documentation. (#790)
* [python/replay] Make specifying 'robot' optional in most helpers. (#800)
* [gym/common] Add generic stacked quantity wrapper. (#783)
* [gym/common] Do NOT pass 'truncated' argument to 'compute_reward'. (#783)
* [gym/common] More generic quantity batching. (#783)
* [gym/common] Pass 'info' in argument of 'has_terminated' for consistency. (#783)
* [gym/common] Remove BaseJiminyEnv 'enforce_bounded_spaces' option by lack of use-case. (#783)
* [gym/common] Add masked quantity. (#784)
* [gym/common] Add average odometry velocity quantity. (#784)
* [gym/common] Introduce reward objects. (#784)
* [gym/common] Add locomotion rewards. (#784)
* [gym/common] Add base reward mixture class to ease pipeline instantiation. (#786)
* [gym/common] Add basic survive reward. (#786)
* [gym/common] Increase timeout ratio from 10 to 15 to avoid Mac OS CI failure. (#786)
* [gym/common] Add compose reward pipeline wrapper. (#787)
* [gym/common] Support specifying reward in pipeline config. (#787)
* [gym/common] Add simulation vs trajectory quantity evaluation mode. (#791)
* [gym/common] Expose trajectory database in quantity manager. (#792)
* [gym/common] Expose interpolate mode for trajectories. (#792)
* [gym/common] Add support of trajectory reference in reward computation. (#792)
* [gym/common] Enable specifying reference trajectories in pipeline config. (#792)
* [gym/common] Get around some memory alignment issue with Boost < 1.78. (#794)
* [gym/zoo] Update Atlas learning environment. (#800)
* [gym/zoo] Update all robotic environments so that random actions do not trigger truncation. (#801)
* [gym/rllib] Add symmetry surrogate loss in rllib custom ppo (#780)
* [gym/rllib] Fix checkpoint save location. (#788)
* [gym/rllib] Update checkpoint_dir so it is dependant on iteration number (#789)
* [misc] Update install instructions on windows. (#787)
  • Loading branch information
duburcqa authored May 24, 2024
1 parent 34713ad commit 8ff3ac6
Show file tree
Hide file tree
Showing 127 changed files with 6,781 additions and 3,333 deletions.
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.12.4)

# Set the build version (specify a tweak version to indicated post-release if needed)
set(BUILD_VERSION 1.8.5.1)
set(BUILD_VERSION 1.8.6)

# MSVC runtime library flags are defined by 'CMAKE_MSVC_RUNTIME_LIBRARY'
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15.7)
Expand Down
37 changes: 18 additions & 19 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ make install -j2

### Prerequisites

You have to preinstall by yourself the (free) MSVC 2019 toolchain.
You have to preinstall by yourself the (free) MSVC 2019+ toolchain.

Then, install `setuptools`, `wheel` and `numpy`.

Expand Down Expand Up @@ -152,24 +152,23 @@ if (-not (Test-Path -PathType Container $RootDir/build)) {
New-Item -ItemType "directory" -Force -Path "$RootDir/build"
}
Set-Location -Path $RootDir/build
cmake "$RootDir" -G "Visual Studio 16 2019" -T "v142" -DCMAKE_GENERATOR_PLATFORM=x64 `
-DCMAKE_INSTALL_PREFIX="$InstallDir" -DCMAKE_MODULE_PATH="$InstallDir" `
cmake "$RootDir" -G "Visual Studio 17 2022" -DCMAKE_GENERATOR_PLATFORM=x64 `
-DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" `
-DCMAKE_INSTALL_PREFIX="$InstallDir" -DCMAKE_PREFIX_PATH="$InstallDir" `
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF -DCMAKE_VERBOSE_MAKEFILE=ON `
-DBOOST_ROOT="$InstallDir" -DBoost_INCLUDE_DIR="$InstallDir/include" `
-DBoost_NO_SYSTEM_PATHS=TRUE -DBoost_NO_BOOST_CMAKE=TRUE `
-DBoost_USE_STATIC_LIBS=OFF `
-DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_PYTHON_INTERFACE=ON `
-DCMAKE_CXX_FLAGS="-DBOOST_ALL_NO_LIB -DBOOST_LIB_DIAGNOSTIC -DBOOST_CORE_USE_GENERIC_CMATH"
cmake --build . --target all --config "${env:BUILD_TYPE}" --parallel 8
if (-not (Test-Path -PathType Container "$RootDir/build/PyPi/jiminy_py/src/jiminy_py/core")) {
New-Item -ItemType "directory" -Force -Path "$RootDir/build/PyPi/jiminy_py/src/jiminy_py/core"
-DBoost_NO_SYSTEM_PATHS=TRUE -DBoost_NO_BOOST_CMAKE=TRUE -DBoost_USE_STATIC_LIBS=ON `
-DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_PYTHON_INTERFACE=ON ``
-DCMAKE_CXX_FLAGS="${env:CMAKE_CXX_FLAGS} $(
) -DBOOST_ALL_NO_LIB -DBOOST_LIB_DIAGNOSTIC -DBOOST_CORE_USE_GENERIC_CMATH $(
) -DEIGENPY_STATIC -DURDFDOM_STATIC -DHPP_FCL_STATIC -DPINOCCHIO_STATIC"
cmake --build . --target ALL_BUILD --config "${env:BUILD_TYPE}" --parallel 2
if (-not (Test-Path -PathType Container "$RootDir/build/pypi/jiminy_py/src/jiminy_py")) {
New-Item -ItemType "directory" -Force -Path "$RootDir/build/pypi/jiminy_py/src/jiminy_py/core"
}
Copy-Item -Path "$InstallDir/lib/boost_numpy*.dll" `
-Destination "$RootDir/build/PyPi/jiminy_py/src/jiminy_py/core"
Copy-Item -Path "$InstallDir/lib/boost_python*.dll" `
-Destination "$RootDir/build/PyPi/jiminy_py/src/jiminy_py/core"
Copy-Item -Path "$InstallDir/lib/site-packages/*" `
-Destination "$RootDir/build/PyPi/jiminy_py/src/jiminy_py" -Recurse
cmake --build . --target install --config "${env:BUILD_TYPE}"
Copy-Item -Force -Recurse -Path "$InstallDir/lib/site-packages/*" `
-Destination "$RootDir/build/pypi/jiminy_py/src/jiminy_py/core"
cmake --build . --target INSTALL --config "${env:BUILD_TYPE}"
```
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ Beside a strong focus on performance to answer machine learning's need for runni

### General

- Simulation of multi-body systems using minimal coordinates and Lagrangian dynamics.
- Simulation of multi-body systems using **minimal coordinates and Lagrangian dynamics**.
- Comprehensive API for computing dynamic quantities and their derivatives thanks to Pinocchio.
- C++ core with full python bindings, providing user API parity between both languages.
- Designed with machine learning in mind, with seamless wrapping of robots as [OpenAI Gym](https://github.com/openai/gym) environments using one-liners. Jiminy provides both the physical engine and the robot model (including sensors) required for learning.
- Rich simulation log output, easily customizable for recording, introspection and debugging. The simulation log is made available in RAM directly for fast access, and can be exported in raw binary or [HDF5](./docs/spec/src/tlmc_format_specification.md) format.
- **Fully modular learning environment pipeline design**, with plug-and-play robotic observers and controllers, but also composable reward components and termination conditions. See example [here](./python/gym_jiminy/unit_py/data/anymal_pipeline.toml).
- Rich simulation log output, easily customizable for recording, introspection and debugging. The simulation log is made available in RAM directly for fast access, and can be exported in binary or [HDF5](./docs/spec/src/tlmc_format_specification.md) format.
- Dedicated integration in Google Colab, Jupyter Lab, Mybinder and VSCode working out-of-the-box - including interactive 3D viewer based on [Meshcat](https://github.com/rdeits/MeshCat.jl). This facilitates working on remote environments.
- Synchronous and single-threaded offscreen rendering capability, GPU-accelerated without graphical server, based on [Panda3d](https://github.com/panda3d/panda3d).
- Easy to install: `pip` is all that is needed to [get you started](#getting-started) ! Support Linux, Mac and Windows platforms.
Expand All @@ -43,7 +44,7 @@ Beside a strong focus on performance to answer machine learning's need for runni
- Provide both classical phenomenological force-level spring-damper contact model and constraint solver satisfying the maximum energy dissipation principle.
- Support contact and collision with the ground from a fixed set of contact points (primitives and meshes yet to come).
- Simulate multiple articulated systems simultaneously interacting with each other, to support use cases such as multi-agent learning or swarm robotics.
- Compliant spherical joints with spring-damper dynamics to model mechanical deformation, a common phenomenon particularly in legged robotics.
- Modeling of motor transmission backlash and structural deformation via compliant spherical joints with spring-damper dynamics, which are common phenomena, particularly in bipedal robotics.
- Simulate both continuous or discrete-time controller, with possibly different controller and sensor update frequencies.

A more complete list of features is available on the [wiki](https://github.com/duburcqa/jiminy/wiki).
Expand Down
7 changes: 4 additions & 3 deletions core/examples/double_pendulum/double_pendulum.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,20 @@ int main(int /* argc */, char * /* argv */[])

// Instantiate and configuration the robot
std::vector<std::string> motorJointNames{"SecondPendulumJoint"};

auto robot = std::make_shared<Robot>();
GenericConfig modelOptions = robot->getModelOptions();
GenericConfig & jointsOptions = boost::get<GenericConfig>(modelOptions.at("joints"));
boost::get<bool>(jointsOptions.at("positionLimitFromUrdf")) = true;
boost::get<bool>(jointsOptions.at("velocityLimitFromUrdf")) = true;
robot->setModelOptions(modelOptions);
robot->initialize(urdfPath.string(), false, {dataPath.string()});
for (const std::string & jointName : motorJointNames)
{
auto motor = std::make_shared<SimpleMotor>(jointName);
robot->attachMotor(motor);
motor->initialize(jointName);
GenericConfig motorOptions = motor->getOptions();
boost::get<bool>(motorOptions.at("velocityLimitFromUrdf")) = true;
motor->setOptions(motorOptions);
}

// Instantiate and configuration the controller
Expand All @@ -95,7 +96,7 @@ int main(int /* argc */, char * /* argv */[])
boost::get<bool>(telemetryOptions.at("enableAcceleration")) = true;
boost::get<bool>(telemetryOptions.at("enableForceExternal")) = false;
boost::get<bool>(telemetryOptions.at("enableCommand")) = true;
boost::get<bool>(telemetryOptions.at("enableMotorEffort")) = true;
boost::get<bool>(telemetryOptions.at("enableEffort")) = true;
boost::get<bool>(telemetryOptions.at("enableEnergy")) = true;
GenericConfig & worldOptions = boost::get<GenericConfig>(simuOptions.at("world"));
boost::get<Eigen::VectorXd>(worldOptions.at("gravity"))[2] = -9.81;
Expand Down
6 changes: 4 additions & 2 deletions core/examples/external_project/double_pendulum.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,19 @@ int main(int argc, char * argv[])
GenericConfig modelOptions = robot->getModelOptions();
GenericConfig & jointsOptions = boost::get<GenericConfig>(modelOptions.at("joints"));
boost::get<bool>(jointsOptions.at("positionLimitFromUrdf")) = true;
boost::get<bool>(jointsOptions.at("velocityLimitFromUrdf")) = true;
robot->setModelOptions(modelOptions);
robot->initialize(urdfPath.string(), false, {});

// Attach motor and encoder to the robot
auto motor = std::make_shared<SimpleMotor>("motor");
robot->attachMotor(motor);
motor->initialize("SecondPendulumJoint");
GenericConfig motorOptions = motor->getOptions();
boost::get<bool>(motorOptions.at("velocityLimitFromUrdf")) = true;
motor->setOptions(motorOptions);
auto sensor = std::make_shared<EncoderSensor>("encoder");
robot->attachSensor(sensor);
sensor->initialize("SecondPendulumJoint");
sensor->initialize("SecondPendulumJoint", true);

// Print encoder sensor index
std::cout << "Encoder sensor index: " << sensor->getIndex() << std::endl;
Expand Down
37 changes: 7 additions & 30 deletions core/include/jiminy/core/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ namespace jiminy
Eigen::VectorXd command{};
Eigen::VectorXd u{};
Eigen::VectorXd uMotor{};
Eigen::VectorXd uTransmission{};
Eigen::VectorXd uInternal{};
Eigen::VectorXd uCustom{};
ForceVector fExternal{};
Expand Down Expand Up @@ -198,9 +199,9 @@ namespace jiminy
std::vector<std::string> logPositionFieldnames{};
std::vector<std::string> logVelocityFieldnames{};
std::vector<std::string> logAccelerationFieldnames{};
std::vector<std::string> logEffortFieldnames{};
std::vector<std::string> logForceExternalFieldnames{};
std::vector<std::string> logCommandFieldnames{};
std::vector<std::string> logMotorEffortFieldnames{};
std::string logEnergyFieldname{};

/// \brief Internal buffer with the state for the integration loop.
Expand Down Expand Up @@ -283,15 +284,6 @@ namespace jiminy
return config;
};

GenericConfig getDefaultJointOptions()
{
GenericConfig config;
config["boundStiffness"] = 1.0e7;
config["boundDamping"] = 1.0e4;

return config;
};

GenericConfig getDefaultWorldOptions()
{
GenericConfig config;
Expand Down Expand Up @@ -337,9 +329,9 @@ namespace jiminy
config["enableVelocity"] = true;
config["enableAcceleration"] = true;
config["enableForceExternal"] = false;
config["enableCommand"] = true;
config["enableMotorEffort"] = true;
config["enableEnergy"] = true;
config["enableCommand"] = false;
config["enableEffort"] = false;
config["enableEnergy"] = false;
return config;
};

Expand All @@ -349,7 +341,6 @@ namespace jiminy
config["telemetry"] = getDefaultTelemetryOptions();
config["stepper"] = getDefaultStepperOptions();
config["world"] = getDefaultWorldOptions();
config["joints"] = getDefaultJointOptions();
config["constraints"] = getDefaultConstraintOptions();
config["contacts"] = getDefaultContactOptions();

Expand Down Expand Up @@ -394,18 +385,6 @@ namespace jiminy
}
};

struct JointOptions
{
const double boundStiffness;
const double boundDamping;

JointOptions(const GenericConfig & options) :
boundStiffness{boost::get<double>(options.at("boundStiffness"))},
boundDamping{boost::get<double>(options.at("boundDamping"))}
{
}
};

struct WorldOptions
{
const Eigen::VectorXd gravity;
Expand Down Expand Up @@ -460,7 +439,7 @@ namespace jiminy
const bool enableAcceleration;
const bool enableForceExternal;
const bool enableCommand;
const bool enableMotorEffort;
const bool enableEffort;
const bool enableEnergy;

TelemetryOptions(const GenericConfig & options) :
Expand All @@ -470,7 +449,7 @@ namespace jiminy
enableAcceleration{boost::get<bool>(options.at("enableAcceleration"))},
enableForceExternal{boost::get<bool>(options.at("enableForceExternal"))},
enableCommand{boost::get<bool>(options.at("enableCommand"))},
enableMotorEffort{boost::get<bool>(options.at("enableMotorEffort"))},
enableEffort{boost::get<bool>(options.at("enableEffort"))},
enableEnergy{boost::get<bool>(options.at("enableEnergy"))}
{
}
Expand All @@ -481,15 +460,13 @@ namespace jiminy
const TelemetryOptions telemetry;
const StepperOptions stepper;
const WorldOptions world;
const JointOptions joints;
const ConstraintOptions constraints;
const ContactOptions contacts;

EngineOptions(const GenericConfig & options) :
telemetry{boost::get<GenericConfig>(options.at("telemetry"))},
stepper{boost::get<GenericConfig>(options.at("stepper"))},
world{boost::get<GenericConfig>(options.at("world"))},
joints{boost::get<GenericConfig>(options.at("joints"))},
constraints{boost::get<GenericConfig>(options.at("constraints"))},
contacts{boost::get<GenericConfig>(options.at("contacts"))}
{
Expand Down
59 changes: 32 additions & 27 deletions core/include/jiminy/core/hardware/abstract_motor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ namespace jiminy
/// state of every motor.
struct MotorSharedStorage
{
/// \brief Buffer storing the current true motor efforts.
Eigen::VectorXd data_;
/// \brief Buffer storing the current motor efforts on joint and motor sides respectively.
Eigen::MatrixX2d data_;
/// \brief Vector of pointers to the motors.
std::vector<AbstractMotorBase *> motors_;
/// \brief Number of motors
Expand All @@ -43,9 +43,10 @@ namespace jiminy
{
GenericConfig config;
config["mechanicalReduction"] = 1.0;
config["enableCommandLimit"] = true;
config["commandLimitFromUrdf"] = true;
config["commandLimit"] = 0.0;
config["velocityLimitFromUrdf"] = true;
config["velocityLimit"] = 0.0;
config["effortLimitFromUrdf"] = true;
config["effortLimit"] = 0.0;
config["enableArmature"] = false;
config["armature"] = 0.0;
config["enableBacklash"] = false;
Expand All @@ -58,19 +59,21 @@ namespace jiminy
{
/// \brief Mechanical reduction ratio of transmission (joint/motor), usually >= 1.0.
const double mechanicalReduction;
const bool enableCommandLimit;
const bool commandLimitFromUrdf;
const double commandLimit;
const bool velocityLimitFromUrdf;
const double velocityLimit;
const bool effortLimitFromUrdf;
const double effortLimit;
const bool enableArmature;
const double armature;
const bool enableBacklash;
const double backlash;

AbstractMotorOptions(const GenericConfig & options) :
mechanicalReduction(boost::get<double>(options.at("mechanicalReduction"))),
enableCommandLimit(boost::get<bool>(options.at("enableCommandLimit"))),
commandLimitFromUrdf(boost::get<bool>(options.at("commandLimitFromUrdf"))),
commandLimit(boost::get<double>(options.at("commandLimit"))),
velocityLimitFromUrdf(boost::get<bool>(options.at("velocityLimitFromUrdf"))),
velocityLimit(boost::get<double>(options.at("velocityLimit"))),
effortLimitFromUrdf(boost::get<bool>(options.at("effortLimitFromUrdf"))),
effortLimit(boost::get<double>(options.at("effortLimit"))),
enableArmature(boost::get<bool>(options.at("enableArmature"))),
armature(boost::get<double>(options.at("armature"))),
enableBacklash(boost::get<bool>(options.at("enableBacklash"))),
Expand All @@ -84,7 +87,7 @@ namespace jiminy

public:
/// \param[in] name Name of the motor.
explicit AbstractMotorBase(const std::string & name) noexcept;
explicit AbstractMotorBase(const std::string & name);
virtual ~AbstractMotorBase();

/// \brief Refresh the proxies.
Expand All @@ -105,10 +108,11 @@ namespace jiminy
const GenericConfig & getOptions() const noexcept;

/// \brief Actual effort of the motor at the current time.
double get() const;
std::tuple<double, double> get() const;

/// \brief Actual effort of all the motors at the current time.
const Eigen::VectorXd & getAll() const;
std::tuple<Eigen::Ref<const Eigen::VectorXd>, Eigen::Ref<const Eigen::VectorXd>>
getAll() const;

/// \brief Set the configuration options of the motor.
///
Expand Down Expand Up @@ -138,22 +142,22 @@ namespace jiminy
/// \brief Index of the joint associated with the motor in the kinematic tree.
pinocchio::JointIndex getJointIndex() const;

/// \brief Type of joint associated with the motor.
JointModelType getJointType() const;
/// \brief Maximum position of the actuated joint translated on motor side.
double getPositionLimitLower() const;

/// \brief Index of the joint associated with the motor in configuration vector.
Eigen::Index getJointPositionIndex() const;
/// \brief Minimum position of the actuated joint translated on motor side.
double getPositionLimitUpper() const;

/// \brief Index of the joint associated with the motor in the velocity vector.
Eigen::Index getJointVelocityIndex() const;
/// \brief Maximum velocity of the motor.
double getVelocityLimit() const;

/// \brief Maximum effort of the motor.
double getCommandLimit() const;
double getEffortLimit() const;

/// \brief Rotor inertia of the motor.
/// \brief Rotor inertia of the motor on joint side.
double getArmature() const;

/// \brief Backlash of the transmission.
/// \brief Backlash of the transmission on joint side.
double getBacklash() const;

/// \brief Request the motor to update its actual effort based of the input data.
Expand Down Expand Up @@ -193,7 +197,7 @@ namespace jiminy

protected:
/// \brief Reference to the last data buffer corresponding to the true effort of the motor.
double & data();
std::tuple<double &, double &> data();

private:
/// \brief Attach the sensor to a robot
Expand Down Expand Up @@ -223,9 +227,10 @@ namespace jiminy
std::string jointName_{};
pinocchio::JointIndex jointIndex_{0};
JointModelType jointType_{JointModelType::UNSUPPORTED};
Eigen::Index jointPositionIndex_{0};
Eigen::Index jointVelocityIndex_{0};
double commandLimit_{0.0};
double positionLimitLower_{};
double positionLimitUpper_{};
double velocityLimit_{0.0};
double effortLimit_{0.0};
double armature_{0.0};
double backlash_{0.0};

Expand Down
Loading

0 comments on commit 8ff3ac6

Please sign in to comment.