(OUTDATED. Please check our new documentation )
(v.0.6.0)
by Jemin Hwangbo
last updated: 10/29/2019
created: 2/21/2019
Click the chapters
RaiSim is a physics engine developed by the researchers at Robotic Systems Lab, ETH Zurich. It was designed to provide both the accuracy and speed for simulating robotic systems. However, it is a generic rigid-body simulator and can simulate any rigid body efficiently.
References:
overview
Math
Eigen::VectorXd vectorEigen;
VecDyn vectorRaiSim;
// ... after some algebraic manipulation
// raisim type to eigen type
// (deosn't matter if it is dynamic or static type)
vectorEigen = vectorRaiSim.e();
// eigen type to raisim type
vectorRaiSim = vectorEigen;
raisim::Vec; raisim::VecDyn; raisim::Mat; raisim::MatDyn;
raisim::SparseJacobian; raisim::SparseJacobian1D;
Messages
The purpose of this debug prefix is to prevent unnecessary checks in release mode. You can also add suffix "_IF" if you make it conditional. E.g.,
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DRSDEBUG)
else ()
remove_definitions(-DRSDEBUG)
endif ()
RSINFO(""), RSWARN(""), RSFATAL("")
RSWARN_IF(val<0, "the value is negative")
continued on the next page
Messages
The fatal behavior is "exit(1)" by default. You can customize the behavior as
raisim::RaiSimMsg::setFatalCallback([](){throw;});
auto ball = world.addSphere(1, 1); // radius and mass
definitions
1. Degrees of freedom: dimension of the minimum representation of the velocity state of a system. Henceforth denoted as \(n\)
2. Generalized velocity: a minimum parameterization of a velocity state of the system (\(\in\mathbb{R}^n\))
3. Generalized coordinate: a parameterization of a configuration of the system (\(\in\mathbb{R}^m\))
4. Generalized state: a generalized velocity and coordinate
(\(\in\mathbb{R}^{n+m}\))
5. Generalized force: external dynamical influences expressed in the generalized velocity space (\(\in\mathbb{R}^{n}\))
Many systems like a robot arm and a cart pole have a fixed-base. A fixed-base should be connected to the link "World" with a fixed joint. For example,
Fixed-base systems
<robot name="2DrobotArm">
<link name="world"/>
<link name="link1"/>
<joint name="worldTolink1" type="fixed">
<parent link="world"/>
<child link="link1"/>
<origin xyz="0 0 0"/>
</joint>
<link name="link2">
<inertial>
<origin rpy="0 0 0" xyz="0.0 0.0 0.2"/>
<mass value="1"/>
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
</inertial>
</link>
<joint name="link1Tolink2" type="revolute">
<parent link="link1"/>
<child link="link2"/>
<origin xyz="0 0 0.3"/>
<axis xyz="1 0 0"/>
<limit effort="80" lower="-1" upper="1" velocity="15"/>
</joint>
</robot>
For a cart pole, there are four links in the URDF. 1. World 2. the Fixed-base (rail) 3. the cart and 4. the pole. You might be thinking that defining a rail might not be necessary. But such a convention makes the methods in AS consistent for both floating- and fixed- base systems.
Fixed-base systems URDF
generalized coordinate, generalized velocity
***Where \(\phi_i\) and \(u_i\) are GC and GV of each joint. Note that \(\dot{\phi}\) might not be equal to \(\mathbf{u}\)!
Each joint state can also be a vector (for spherical joints)
\(\mathbf{\phi}_i\), \(\mathbf{u}_i\) of different joints. All quantities are expressed in and with respect to the parent frame. For the floating base, the parent is the world frame.
Floating base:
Revolute and prismatic joints:
Spherical joints:
generalized coordinate, generalized velocity
\(\mathbf{\phi}_i\), \(\mathbf{u}_i\) of different joints. All quantities are expressed in and with respect to the parent frame. For the floating base, the parent is the world frame.
Floating base:
Revolute and prismatic joints:
Spherical joints:
Quaternion
Position
Linear velocity
Angular velocity
Quaternion
Angular velocity
Joint position
Joint velocity
generalized coordinate, generalized velocity
Example: pogo stick
Pogo stick has one prismatic joint and thus two bodies (a floating base and a foot).
Floating base:
prismatic joints:
generalized coordinate, generalized velocity
Eigen::MatrixXd M(robot->getDOF(),robot->getDOF());
Eigen::VectorXd h(robot->getDOF());
M = robot->getMassMatrix();
h = robot->getNonlinearites();
Dynamics quantities
auto imuFrame = robot->getFrameIdxByName("imu_joint");
raisim::Vec<3> position;
raisim::Mat<3,3> orientation;
robot->getFramePosition(imuFrame, position);
robot->getFrameOrientation(imuFrame, orientation);
Bodies and joints
raisim::SparseJacobians jaco;
raisim::VecDyn gv(robot->getDOF());
robot->getSparseJacobian(n, {1,1,1}, jaco);
robot->getGeneralizedVelocity(gv);
raisim::Vec<3> vel;
raisim::matmul(jaco, gv, vel);
(sparse) Jacobians
Eigen::MatrixXd jaco(3, robot->getDOF());
Eigen::VectorXd gv(robot->getDOF());
robot->getDenseJacobian(n, {1,1,1}, jaco);
gv = robot->getGeneralizedVelocity();
Eigen::Vector<3> vel;
vel = jaco * gv;
Sparse (RaiSim) way
Dense (Eigen) way
robot->getCollisionBodies().get("left_foot/0")->material = "rubber";
Collision object
auto colIterator = robot->getCollisionBodies().get("left_foot/0");
colIterator->material = "rubber";
Visual object
PD control
Rotor inertia
Joint/Link API
raisim::World world;
auto anymal = world->addArticulatedSystem("PATH_TO_URDF");
auto hipJoint = anymal->getJoint("LF_HIP");
raisim::Vec<3> pos;
raisim::Mat<3,3> rot;
hipJoint->getPosition(pos);
hipJoint->getOrientation(rot);
auto shank = anymal->getLink("LF_SHANK");
shank.setComPositionInParentFrame({0., 1.0, 0.0}); // change dynamic properties online
world->integrate();
1. Detailed example can be found in "creatingRobotUsingCPP" example in raisimOgre
2. raisim::World class has addAritculatedSystem(const Child &, ...) method. raisim::Child is a class that defines a kinematic tree. It contains a body, a joint and Children (a group of Child). Children are either child or fixedBodies. child can move with respect to the parent, fixedBodies cannot (and therefore contains a fixed joint).
A body can have multiple CollisionBody's and VisObject. All bodies and joints must have a unique name
Programmatically create an articulated system
sphere->setBodyType(raisim::BodyType::STATIC);
References:
Continued on the next page
Bouncing
velocity
Impact
velocity
\( \widehat{\epsilon}\)
\( \epsilon\)
Continued on the next page
Continued on the next page
raisim::World->setMaterialPairProp("steel","aluminum", 0.8, 0., 0.);
raisim::World->setDefaultMaterial(0.8, 0., 0.);
Continued on the next page
You can also programatically set the material, e.g.,
note that collision bodies have a name "LINK_NAME/X", where X is the number assigned for collision bodies
<link name="base_inertia">
<collision>
<origin rpy="1.57079632679 0 0" xyz="0.0 0.07 -0.25"/>
<geometry>
<cylinder length="0.08" radius="0.04"/>
</geometry>
<material>
<contact name="steel"/>
</material>
</collision>
</link>
robot->getCollisionBody("base/0").setMaterial("steel");
Continued on the next page
2. For raisim::SingleBodyObject, material properties are defined at instantiation. E.g.,
If not material is assigned, gets default material "" (empty) and it will have the default material property
world.addSphere(1., 1., "steel");
1. RaiSim uses a standard way to filter out unwanted collision, using collision groups and collision masks. Each object belongs to one or multiple collision groups and contains a collision mask. Both collision groups and masks are unsigned long int and can be interpreted as 32-long bit field.
The collision logic is as follows:
Collision group and collision mask
if( (ObjectA->collisionGroup & ObjectB->collisionMask) ||
(ObjectB->collisionGroup & ObjectA->collisionMask) )
collide();
1. Information on contacts on an object can be obtained using Object::getContact(). If this method is called before raisim::World::integrate1(), the contacts are for the last time steps. If it is called after the raisim::World::integrate1(), the contacts are for the current time step
2. When two objects collide, one of them is called "objectA" and the other is called "objectB". The contact impulse is defined in the contact frame of "objectA" and its z-axis is into "objectA". It is also called a contact normal (perpendicular to the surface). The choice of the X-axis and the Y-axis of a contact frame is arbitrary.
1. RaiSim has an algorithm to remove object inter-penetrations which can arise due to numerical errors. It adds a spring and a damping term. The spring stiffness is determined such that the contact point has a separating velocity of erp1 times the depth of the penetration. The damping coefficient is exactly equivalent to the restitution coefficient and the effective restitution coefficient is erp2 + the original restitution coefficient of the material pair. The erp1 and erp2 are global and specified in the world.
Error reduction
raisim::World class manages all resources. Currently, you can only dynamically generate the world. We are working on a method of generating a world from a script.
Users can dynamically add or remove objects in RaiSim. However, add or remove object methods should not be called between integrate1() and integrate2() calls.
Dynamic world editing
Raisim is a physics engine and does not contain any visualizer. However, we provide an open-source visualizer based on Ogre3d, which can be found at
We provide an open-source example of RL using raisim at
A python wrapper developed by Brian Delhaisse is available here:
#include “raisim/World.hpp”
int main() {
raisim::World world;
auto anymal = world.addArticulatedSystem(“pathToURDF”);
auto ball = world.addSphere(1, 1); // radius and mass
auto ground = world.addGround();
world.setTimeStep(0.002);
world.integrate();
}
The following code simulates a robot and a sphere on a flat ground for one time step