Menu

Worldsim

Tomassino Ferrauto Stefano Nolfi
Attachments
worldsim-example.png (1899216 bytes)
Prev: The Arena Component Up: Customizing the environment Next: Using robots

Table of contents

The Worldsim Library

The Worldsim library allows to create objects with different basic shapes (e.g. boxes, spheres, cylinders etc.) that can be combined to create more complex objects. The elements forming complex objects can be connected either through fixed joints, that do not allow relative motions of the parts, or through joints that allow traslation or rotation of the parts with respect to defined axes. Objects combined through joints can be used to create articulated entities. This library is also at the basis of the Arena component.

In this page we show a portion of the source code of the WorldsimShowcase plugin that creates the objects shown in the picture below. The function of the different instructions is commented on the source code itself.

Worldsim is based on the Newton Dynamics open source physics engine, wrapped in an object oriented API. World is the main class of the Worldsim library and it contains all information about the objects sostituting the world (type, position, material etc.). Throughout the library (and also in other parts of FARSA), wVector is the class used to represent tridimensional vectors and points, while wMatrix is the class used to represent 4x4 rotational and traslational matrices. For detailed informations about the World, wVector and wMatix classes refer to the API documentation.

In experimental plugins based on the EvoRobotExperiment class, the World instance is created automatically and the timestep can be configured though a configuration parameter. In the case of other types of experimental plugins, instead, it should be created manually as in WorldsimShowcase plugin.

:::C++
// In the followin function, m_world is the instance of the World class
void WorldsimShowcase::createShowcase()
{
    // Creating a static object. Static objects are not influenced by external forces, including gravity
    // All objects are created by default at the center of the world and have a standard texture
    PhyBox* table = new PhyBox(2.0, 2.0, 0.1, m_world);
    table->setStatic(true);
    table->setColor(Qt::white);

    // Creating various objects and putting them above the table. They will fall by gravity when the
    // simulation starts

    // A sphere.
    PhySphere* sphere = new PhySphere(0.2, m_world);
    sphere->setMass(0.1);
    sphere->setTexture("");
    sphere->setColor(Qt::red);
    sphere->setPosition(0.0, 0.0, 1.0);

    // A cone. The cone is rotated so that the tip is pointing downward
    PhyCone* cone = new PhyCone(0.1, 0.4, m_world);
    cone->setMass(0.2);
    cone->setColor(Qt::yellow);
    wMatrix mtr = wMatrix::yaw(M_PI_2); // rotation by pi/2 radiants around the Y axis
    mtr.w_pos = wVector(0.0, 0.5, 1.5); // setting position in the transformation matrix
    cone->setMatrix(mtr);

    // A cylinder. The cylinder has an initial angular velocity along its axis. We also display
    // its frame of reference. Note that there is no floor, so if the object falls from the table
    // it will keep falling beyound the lower boundary of the world (that is only graphical)
    PhyCylinder* cylinder = new PhyCylinder(0.15, 0.3, m_world);
    cylinder->setMass(1.0);
    cylinder->setColor(Qt::green);
    cylinder->setOmega(wVector(10.0, 0.0, 0.0));
    cylinder->setPosition(0.0, -0.5, 0.7);
    cylinder->drawLocalAxes(true);

    // A compound object, made up of an elongated box with an ellipsoind on top. First we create the
    // components, then we put them together. The position of the components will be used as the relative
    // position in the compound object frame of reference. We also display the compound object frame of
    // reference
    PhyBox* box = new PhyBox(0.1, 0.1, 0.4, m_world);
    box->setPosition(0.0, 0.0, 0.1);
    PhyEllipsoid* ellipsoid = new PhyEllipsoid(0.2, 0.2, 0.1, m_world);
    ellipsoid->setPosition(0.0, 0.0, 0.35);
    PhyCompoundObject* compound = new PhyCompoundObject(QVector<PhyObject*>() << box << ellipsoid, m_world);
    compound->setPosition(0.7, -0.7, 1.0);
    compound->setColor(Qt::white);
    compound->drawLocalAxes(true);

    // An hinge joint between a box and a cylinder. The hinge has a lower and upper limit to its movement.
    // We also apply an initial velocity to the cylinder
    PhyBox* hBox = new PhyBox(0.4, 0.4, 0.1, m_world);
    hBox->setMass(1.0);
    hBox->setPosition(0.7, 0.0, 0.5);
    hBox->setColor(QColor(255, 190, 0));
    PhyCylinder* hCylinder = new PhyCylinder(0.05, 0.3, m_world);
    hCylinder->setMass(0.1);
    mtr = wMatrix::yaw(M_PI_2);
    mtr.w_pos = wVector(0.5, 0.0, 0.65);
    hCylinder->setMatrix(mtr);
    // Setting a slow initial velocity so that the cylinder does not remain vertical (that is an unstable
    // equilibrium point)
    hCylinder->setOmega(wVector(0.0, 1.0, 0.0));
    hCylinder->setColor(QColor(190, 255, 0));
    PhyHinge* hinge = new PhyHinge(wVector(0.0, 1.0, 0.0), wVector(-0.2, 0.0, 0.0), hBox, hCylinder);
    hinge->dofs()[0]->setLimits(-M_PI / 3.0, M_PI / 3.0);
    // Allow free movement (otherwise a motor tries to keep the objects in their starting position)
    hinge->dofs()[0]->switchOff();
    hinge->dofs()[0]->enableLimits();

    // A ball-and-socket joint. The box is jointed "to the world" (the first object is NULL)
    PhyBox* bsBox = new PhyBox(0.4, 0.1, 0.1, m_world);
    bsBox->setPosition(0.7, 0.7, 0.3);
    bsBox->setColor(Qt::blue);
    PhyBallAndSocket* bsJoint = new PhyBallAndSocket(wVector(0.5, 0.7, 0.3), NULL, bsBox);
    // The ball-and-socket joint has no motor

    // Creating an inclined plane to show collisions and materials
    PhyBox* inclinedPlane = new PhyBox(0.5, 2.0, 0.1, m_world);
    inclinedPlane->setStatic(true);
    mtr = wMatrix::yaw(-M_PI / 8);
    mtr.w_pos = wVector(-0.5, 0.0, 0.15);
    inclinedPlane->setMatrix(mtr);

    // Adding a new material to the world and setting it to be the material of the inclined plane
    m_world->materials().createMaterial("inclinedPlaneMaterial");
    inclinedPlane->setMaterial("inclinedPlaneMaterial");

    // Adding a normal box that falls on the plane. The box has the standard material
    PhyBox* matBox = new PhyBox(0.2, 0.2, 0.2, m_world);
    mtr = wMatrix::yaw(-M_PI / 8);
    mtr.w_pos = wVector(-0.5, 0.7, 0.35);
    matBox->setMatrix(mtr);
    matBox->setColor(Qt::white);

    // Now creating a box with a custom material and setting the friction between the box and
    // the inclined plane material to a low value
    m_world->materials().createMaterial("boxMaterial");
    m_world->materials().setFrictions("boxMaterial", "inclinedPlaneMaterial", 0.001, 0.001);
    PhyBox* frictionBox = new PhyBox(0.2, 0.2, 0.2, m_world);
    mtr = wMatrix::yaw(-M_PI / 8);
    mtr.w_pos = wVector(-0.5, 0.0, 0.35);
    frictionBox->setMatrix(mtr);
    frictionBox->setColor(Qt::green);
    frictionBox->setMaterial("boxMaterial");

    // Finally creating a box with another custom materia that doesn't collide with the inclined
    // plane material
    m_world->materials().createMaterial("shadowBoxMaterial");
    m_world->materials().enableCollision("shadowBoxMaterial", "inclinedPlaneMaterial", false);
    PhyBox* shadowBox = new PhyBox(0.2, 0.2, 0.2, m_world);
    mtr = wMatrix::yaw(-M_PI / 8);
    mtr.w_pos = wVector(-0.5, -0.7, 0.35);
    shadowBox->setMatrix(mtr);
    shadowBox->setColor(Qt::red);
    shadowBox->setMaterial("shadowBoxMaterial");
}

Related

Manual: APIDoc
Manual: ArenaComponent
Manual: CustomizeEnvironment
Manual: CustomizingRobots
Manual: Home

Discussion

Anonymous
Anonymous

Add attachments
Cancel