Cannot get contactgeometry to work (solved).

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Sietse Achterop
Posts: 72
Joined: Tue Sep 14, 2021 3:01 am

Cannot get contactgeometry to work (solved).

Post by Sietse Achterop » Mon Sep 27, 2021 5:13 am

Hello,
I do not understand how I can create bodies with contract geometry.
It seems to work completely different then Gazebo that I am used to.
I created, using python, a model consisting of 2 bricks. The idea is that one is a ground floor (the rowing course) and the other a box (the boat) that should fall onto the ground floor. Eventually, there should be friction between the 2 bricks, so the boat can be pulled over the ground with a friction similar to a boat in the water.
bootbaan.png
bootbaan.png (546.09 KiB) Viewed 480 times
This is the picture in opensim when I load the model. If simulation is started, after the first step the boat is vanished and nothing happens afterwards. I would have hoped that the boat would fall on the floor due to gravity.


I tried so make the program below (that creates the osim file) as simple as possible. Only 2 bodies and 2 joints.
Both a Geometry and a ContactGeometry is added to each body.
I would have hoped that this would make it so that the bodies will collide in simulation, but alas, no.

How can I create the intended behavior in opensim?

Thanks in advance, Sietse

Code: Select all

import opensim as osim
import sys

arm = osim.Model()
arm.setName("BootBaan")
arm.setGravity(osim.Vec3(0, -9.90665, 0))

theCourse = osim.Body("The_rowing_course",
                     1.0,
                     osim.Vec3(0, 0, 0),
                     osim.Inertia(0, 0, 0))
                     
theCourseGeometry = osim.Brick(osim.Vec3(10, 0.05, 2))
theCourse.attachGeometry(theCourseGeometry)
theCourseGeometry.setColor(osim.Vec3(0,0,1))

theCourseContactSpace = osim.ContactHalfSpace(osim.Vec3(0, 0.2, 0),
                                              osim.Vec3(0, 0, -1.57),
                                              theCourse)
theCourseContactSpace.setName("baantje")
arm.addContactGeometry(theCourseContactSpace)

theBoat = osim.Body("The_boat",
                     1.0,
                     osim.Vec3(0, 0, 0),
                     osim.Inertia(0, 0, 0))
                     
theBoatGeometry = osim.Brick(osim.Vec3(3, 0.05, 0.5))
theBoat.attachGeometry(theBoatGeometry)
theBoatGeometry.setColor(osim.Vec3(0,1,1))

theBoatContactSpace = osim.ContactHalfSpace(osim.Vec3(0, 0.2, 0),
                                           osim.Vec3(0, 0, -1.57),
                                           theBoat)
theBoatContactSpace.setName("bootje")
arm.addContactGeometry(theBoatContactSpace)


courseJoint = osim.WeldJoint("courseJoint",
                        arm.getGround(),
                        osim.Vec3(0, 0.025, 0),
                        osim.Vec3(0, 0, 0),
                        theCourse,
                        osim.Vec3(0, 0, 0),
                        osim.Vec3(0, 0, 0))
                        
boatJoint = osim.PinJoint("boatJoint",
                        theCourse,
                        osim.Vec3(0, 2, 0),
                        osim.Vec3(0, 0, 0),
                        theBoat,
                        osim.Vec3(0, 0, 0),
                        osim.Vec3(0, 0, 0))
                        
arm.addBody(theCourse)
arm.addBody(theBoat)
arm.addJoint(courseJoint)
arm.addJoint(boatJoint)

arm.initSystem()
arm.printToXML("BootBaan.osim")
EDIT: I used a PinJoint here, so the boat should not fall, but (due to round off errors) at least move. I have seen that in other examples.
Also tried a FreeJoint, but then there is a Simbody exception: Matrix is singular, so can't be inverted.
Last edited by Sietse Achterop on Wed Nov 03, 2021 3:13 am, edited 1 time in total.

User avatar
Thomas Uchida
Posts: 1777
Joined: Wed May 16, 2012 11:40 am

Re: Cannot get contactgeometry to work.

Post by Thomas Uchida » Mon Sep 27, 2021 6:08 am

There is a detailed example in the documentation that might help (the "Building a Dynamic Walker in Matlab" example): https://simtk-confluence.stanford.edu:8 ... +in+Matlab.

User avatar
Sietse Achterop
Posts: 72
Joined: Tue Sep 14, 2021 3:01 am

Re: Cannot get contactgeometry to work.

Post by Sietse Achterop » Tue Sep 28, 2021 5:52 am

Thanks again!
I did look at the dynamic walker but forgot to use the force; but that was easy to add.
Also, I realized that 2 half-spaces would not work, so I used a sphere. I now have a bouncing ball, progress!

If however I change the following (around line 37)

Code: Select all

theBoatContactSphere = osim.ContactSphere()
theBoatContactSphere.setRadius(0.2)
which work, into

Code: Select all

theBoatContactSphere = osim.ContactMesh('stepBox2.obj', osim.Vec3(0, 0, 0), osim.Vec3(0, 0, 0), theBoat)
then visually the contactMesh appears, but the object falls though the lower object!
Why doesn't the ContactMesh work?

Another question is, how can I create a large brick for use as a contact object?
Apart from the above problem, do I really need to create a mesh for this?
I was hoping to be able to use the Brick.

Thanks again, Sietse

PS. For completeness I include the complete Python code.

Code: Select all

import opensim as osim
import sys

arm = osim.Model()

arm.setUseVisualizer(True)

arm.setName("BootBaan")
arm.setGravity(osim.Vec3(0, -9.90665, 0))

theCourse = osim.Body("The_rowing_course",
                     1.0,
                     osim.Vec3(0, 0, 0),
                     osim.Inertia(0, 0, 0))
                     
theCourseGeometry = osim.Brick(osim.Vec3(10, 0.05, 2))
theCourse.attachGeometry(theCourseGeometry)
theCourseGeometry.setColor(osim.Vec3(0,0,1))

theCourseContactSpace = osim.ContactHalfSpace(osim.Vec3(0, 0.2, 0),
                                              osim.Vec3(0, 0, -1.57),
                                              theCourse)
theCourseContactSpace.setName("baantje")
arm.addContactGeometry(theCourseContactSpace)

theBoat = osim.Body()
theBoat.setName('TheBoat')
theBoat.setMass(1)
theBoat.setInertia(osim.Inertia(1,1,1,0,0,0))

theBoatGeometry = osim.Sphere(0.2)

#theBoat.attachGeometry(theBoatGeometry)
theBoat.attachGeometry(osim.Mesh('stepBox2.obj'))
theBoatGeometry.setColor(osim.Vec3(0,1,1))

#theBoatContactSphere = osim.ContactMesh('stepBox2.obj', osim.Vec3(0, 0, 0), osim.Vec3(0, 0, 0), theBoat)
theBoatContactSphere = osim.ContactSphere()
theBoatContactSphere.setRadius(0.2)
theBoatContactSphere.setLocation(osim.Vec3(0,0,0.0) )
theBoatContactSphere.setFrame(theBoat)
theBoatContactSphere.setName('bootje')
arm.addContactGeometry(theBoatContactSphere)

courseJoint = osim.WeldJoint("courseJoint",
                        arm.getGround(),
                        osim.Vec3(0, 0.025, 0),
                        osim.Vec3(0, 0, 0),
                        theCourse,
                        osim.Vec3(0, 0, 0),
                        osim.Vec3(0, 0, 0))
                        
boatJoint = osim.FreeJoint("boatJoint",
                        theCourse,
                        osim.Vec3(0, 2, 0),
                        osim.Vec3(0, 0, 0),
                        theBoat,
                        osim.Vec3(0, 0, 0),
                        osim.Vec3(0, 0, 0))
                        
# Define Contact Force Parameters
stiffness           = 1000000;
dissipation         = 0.03  #2.0;
staticFriction      = 0  #0.8;
dynamicFriction     = 0  #0.4;
viscousFriction     = 0  #0.4;
transitionVelocity  = 0  #0.2;

# Make a Hunt Crossley Force for Right Hip and update parameters
HuntCrossleyBoat = osim.HuntCrossleyForce();
HuntCrossleyBoat.setName('BoatForce');
HuntCrossleyBoat.addGeometry('bootje');
HuntCrossleyBoat.addGeometry('baantje');
HuntCrossleyBoat.setStiffness(stiffness);
HuntCrossleyBoat.setDissipation(dissipation);
HuntCrossleyBoat.setStaticFriction(staticFriction);
HuntCrossleyBoat.setDynamicFriction(dynamicFriction);
HuntCrossleyBoat.setViscousFriction(viscousFriction);
HuntCrossleyBoat.setTransitionVelocity(transitionVelocity);
arm.addForce(HuntCrossleyBoat);

arm.addBody(theCourse)
arm.addBody(theBoat)
arm.addJoint(courseJoint)
arm.addJoint(boatJoint)

reporter = osim.ConsoleReporter()
reporter.set_report_time_interval(1.0)
arm.addComponent(reporter)

state = arm.initSystem()
manager = osim.Manager(arm)
state.setTime(0)
manager.initialize(state)
state = manager.integrate(10.0)

arm.printToXML("BootBaan.osim")


User avatar
Sietse Achterop
Posts: 72
Joined: Tue Sep 14, 2021 3:01 am

Re: Cannot get contactgeometry to work.

Post by Sietse Achterop » Tue Nov 02, 2021 8:01 am

The reason the ContactMesh didn't work was that it needs the ElasticFoundationForce instead of the HuntCrossleyForce.

POST REPLY