Jurge
Just dropped in
Offline
Posts: 11
|
 |
« on: 14. July 2009, 11:45:09 am » |
|
Dear all, I try to make an simulator with the help of Xith3d (using version 0.9.6-beta1), but I have some difficulties. The collidable objects have strange behavior. When I run the application with asserts enabled. The application give an assert (see output below). I attached a small program (350 lines). The program demonstrates the assertion. Is it a bug or did I forget some thing? With best regards, Jurge The application: package org.prt.simulator;
import java.awt.Font; import java.util.ArrayList;
import net.jtank.input.KeyCode; import net.jtank.input.KeyPressedEvent; import net.jtank.input.KeyReleasedEvent;
import org.jagatoo.datatypes.Sized2iRO; import org.openmali.vecmath2.Colorf; import org.openmali.vecmath2.Matrix3f; import org.openmali.vecmath2.Point3f; import org.openmali.vecmath2.Tuple3f; import org.openmali.vecmath2.Vector3f; import org.xith3d.base.Xith3DEnvironment; import org.xith3d.loop.CanvasFPSListener; import org.xith3d.loop.InputAdapterRenderLoop; import org.xith3d.loop.opscheduler.OperationScheduler; import org.xith3d.physics.PhysicsEngine; import org.xith3d.physics.PhysicsGFXManager; import org.xith3d.physics.collision.CollideableGroup; import org.xith3d.physics.collision.CollisionEngine; import org.xith3d.physics.collision.CollisionResolver; import org.xith3d.physics.collision.collideable.BoxCollideable; import org.xith3d.physics.collision.collideable.PlaneCollideable; import org.xith3d.physics.joode.JoodePhysicsEngine; import org.xith3d.physics.simulation.Body; import org.xith3d.physics.simulation.SimulationEngine; import org.xith3d.physics.simulation.SimulationWorld; import org.xith3d.render.Canvas3D; import org.xith3d.render.Canvas3DFactory; import org.xith3d.render.config.CanvasConstructionInfo; import org.xith3d.scenegraph.BranchGroup; import org.xith3d.ui.hud.HUD; import org.xith3d.ui.hud.widgets.Label; import org.xith3d.ui.text2d.TextAlignment;
/** * Simulator class. Simple simulator for PRT. Can be extended in the near * future. Used units are in S.I. units (meters etc.) */ public class Simulator extends InputAdapterRenderLoop { private PhysicsEngine physicsEngine; private ArrayList<Body> movingObjects = new ArrayList<Body>(); private ArrayList<Point3f> originalPositions = new ArrayList<Point3f>(); private ArrayList<Vector3f> originalVelocities = new ArrayList<Vector3f>(); private RobotBody robotBody;
// Definitions private final float fieldWidth = 6.0f; private final float fieldLength = 9.0f; private final float halfFieldWidth = this.fieldWidth / 2.0f; private final float halfFieldLength = this.fieldLength / 2.0f; private final int robotCount = 6; // at least 1 private float linearVelocity = 1.0f; float angle = 0.0f; float MAX_LINEAR_VELOCITY = 6.0f;
@Override public void onKeyPressed(KeyPressedEvent e) {
switch (e.getKeyCode()) { case KeyCode.VK_NUMPAD_ADD: case KeyCode.VK_PLUS: linearVelocity = Math.min(this.linearVelocity * 1.05f, MAX_LINEAR_VELOCITY); System.out.println("key +: linear velocity set to " + linearVelocity); break; case KeyCode.VK_NUMPAD_SUBTRACT: case KeyCode.VK_MINUS: linearVelocity = Math.max(linearVelocity / 1.05f, 0); System.out.println("key -: linear velocity set to " + linearVelocity); break; case KeyCode.VK_0: case KeyCode.VK_NUMPAD0: linearVelocity = 0.0f; robotBody.getBody().setLinearVelocity(0.0f, 0.0f, 0.0f); robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("0: everything stopped"); break; case KeyCode.VK_BACK_SPACE: robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("BS: rotation stopped"); break;
case KeyCode.VK_UP: if (this.physicsEngine.isEnabled()) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getDirection().mul(this.robotBody.getSpeed()); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } else { this.physicsEngine.setEnabled(true); } System.out.println("Key UP: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case KeyCode.VK_DOWN: if (this.physicsEngine.isEnabled()) { float speed = this.robotBody.getSpeed(); if (speed > 0.0f) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getBody().getLinearVelocity().mul(.5f); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } } else { this.physicsEngine.setEnabled(true); } System.out.println("Key DOWN: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case KeyCode.VK_LEFT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() + 2.0f * (float) Math.PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; case KeyCode.VK_RIGHT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() - 2.0f * (float) Math.PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; } }
@Override public void onKeyReleased(KeyReleasedEvent e) { switch (e.getKeyCode()) { case KeyCode.VK_SPACE: if (this.physicsEngine.isEnabled()) { for (int i = 0; i < this.movingObjects.size(); i++) { final Body body = this.movingObjects.get(i); Tuple3f pos = this.originalPositions.get(i); body.setPosition(pos); Vector3f vel = this.originalVelocities.get(i); vel.scale(1f, 1f, 100f); body.setLinearVelocity(vel); // body.resetAngularVelocity(); body.setRotationMatrix(Matrix3f.IDENTITY); } } else { this.physicsEngine.setEnabled(true); } break; case KeyCode.VK_ESCAPE: this.end(); break; } }
private void addMovingObject(Body body) { this.movingObjects.add(body); this.originalPositions.add(new Point3f(body.getPosition())); this.originalVelocities.add(new Vector3f(body.getLinearVelocity())); }
private void setupPhysicsAndScene(Xith3DEnvironment sceneGraph) { // XPAL world creation final PhysicsEngine physEng = new JoodePhysicsEngine(); final CollisionEngine collEng = physEng.getCollisionEngine(); final SimulationEngine simEng = physEng.getSimulationEngine(); final SimulationWorld simWorld = simEng.newWorld();
simWorld.setStepSize(1000L); simWorld.setGravity(0f, -9.81f, 0f);
final PhysicsGFXManager gfxManager = physEng.getGFXManager(); physEng.getDefaultSurfaceParameters().setParameter("mu", 0.2f); final BranchGroup scene = sceneGraph.addPerspectiveBranch().getBranchGroup(); CollideableGroup environment = collEng.newGroup();
// Create field ground PlaneCollideable ground = collEng.newPlane(0f, 1f, 0f, 0f); PlaneCollideable.setDefaultAppearance("grass.jpg"); gfxManager.directAdd(ground, scene); environment.addCollideable(ground);
// Create the falling bricks... Tuple3f ballPos = new Tuple3f(0.0f, 0.0f, 3.0f + 10.0f);
for (int i = 0; i < robotCount; i++) { Tuple3f robotPos;
if (i == 0) { robotPos = new Tuple3f(ballPos.getX() - 0.175f, ballPos.getY() - 0.1f, 0.05f + 20.0f); } else { robotPos = new Tuple3f( /* x */(i / (float) robotCount) * fieldLength - halfFieldLength, /* y */halfFieldWidth - 0.40f, /* z */0.05f + 10.0f * (i + 1) / robotCount); } Body robot = createRobot(collEng, simWorld, gfxManager, scene, environment, robotPos, "Robot" + Integer.toString(i));
// Add collision resolvers for this robot // i.e. one collision resolver for each previously created moving object (ball, other robots) for (Body movingObject : this.movingObjects) { if (movingObject != robot) { physEng.addCollisionResolver(new CollisionResolver(robot, movingObject)); } }
if (i == 1) { robot.setLinearVelocity((i % 2) / 5.0f, (i % 3) / 3.0f, 0.0f); } } String robotName = movingObjects.get(1).getName() + " (selected)"; movingObjects.get(1).setName(robotName); // 0 is ball; 1 is first robot robotBody = new RobotBody(movingObjects.get(1), physEng);
physEng.addCollisionResolver(new CollisionResolver(environment));
physEng.setEnabled(false); sceneGraph.setPhysicsEngine(physEng); this.physicsEngine = physEng;
}
private Body createRobot(final CollisionEngine collEng, final SimulationWorld simWorld, final PhysicsGFXManager gfxManager, final BranchGroup scene, CollideableGroup environment, Tuple3f position, String name) { BoxCollideable.setDefaultAppearance("crate.png"); BoxCollideable robot = collEng.newBox(0.75f, 0.10f, 0.35f); Body body = simWorld.newBody();
Tuple3f simPos = convertRc2Sim(position.getX(), position.getY(), position.getZ() + robot.getSize().getZ() + 0.01f); body.setMass(20.0f); body.setPosition(simPos); body.addCollideable(robot); body.setName(name);
simWorld.addBody(body); scene.addChild(gfxManager.add(robot)); environment.addCollideable(robot); addMovingObject(body);
System.out.println("Lin. vel. robot=" + body.getLinearVelocity().getX()); System.out.println("Lin. vel. moving object (robot)=" + movingObjects.get(movingObjects.size() - 1).getLinearVelocity().getX());
return body; }
private HUD createInfoHUD(Sized2iRO size, OperationScheduler opScheder) { HUD hud = new HUD(size, 800f, opScheder);
Label info = new Label(hud.getResX(), 40f, "Press SPACE to (re-)start the simulation.", new Font("Verdana", Font.PLAIN, 18), Colorf.WHITE, TextAlignment.CENTER_LEFT); info.setPadding(10f); hud.addWidget(info, 0f, hud.getResY() - info.getHeight());
return (hud); }
public Simulator(CanvasConstructionInfo canvasInfo) throws Exception { super(128f); System.out.println("Hit SPACE to start/reset the simulation, or ESC to exit"); Xith3DEnvironment env = new Xith3DEnvironment(5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f, this);
setupPhysicsAndScene(env); env.addHUD(createInfoHUD(canvasInfo.getDisplayMode(), getOperationScheduler()), getInputManager());
Canvas3D canvas = Canvas3DFactory.create(canvasInfo); env.addCanvas(canvas); this.addFPSListener(new CanvasFPSListener(canvas)); // get an impression of how fast we are simulating
// enable external inputs - keyboard command this.getInputManager().registerKeyboardAndMouse(canvas); this.begin(TimingMode.MICROSECONDS);
}
static Tuple3f convertRc2Sim(float x, float y, float z) { return new Tuple3f(x, z, y); }
public static void main(String[] args) throws Exception { new Simulator(new CanvasConstructionInfo(false, "RoboCup Simulator")); }
public class RobotBody { private Body body = null; private float speed = MAX_LINEAR_VELOCITY;
public RobotBody(Body body, PhysicsEngine physEng) { this.body = body; }
public float getSpeed() { return speed; }
public void setSpeed(float speed) { this.speed = speed; }
public Vector3f getDirection() { Vector3f dir = body.getLinearVelocity(); dir.setY(0.0f); // not interested in vertical speed
if (Float.isNaN(dir.length()) || dir.length() < .001) { if (Float.isNaN(angle)) { angle = 0.0f; } dir = new Vector3f((float) Math.cos(angle), 0.0f, (float) Math.cos(angle)); } else { angle = body.getRotationY(); if (Float.isNaN(angle)) { angle = 0.0f; body.setRotation(0, 0, 0); } } dir.normalize(); return dir; }
public Body getBody() { return this.body; } } }
The output: [INFO] [exec:exec] [INFO] Hit SPACE to start/reset the simulation, or ESC to exit [INFO] Initializing JOODE...ok [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] WARNING: Theme "GTK" could not be loaded. Using Fallback-Theme [INFO] java.lang.AssertionError: 3.490448E-4 [INFO] at net.java.dev.joode.stepper.lcp.BaraffLCPFixedStatic.driveInToRange(BaraffLCPFixedStatic.java:272) [INFO] at net.java.dev.joode.stepper.lcp.BaraffLCPFixedStatic.computeForces(BaraffLCPFixedStatic.java:153) [INFO] at net.java.dev.joode.stepper.EulerStepper.step(EulerStepper.java:400) [INFO] at net.java.dev.joode.stepper.StepUtils.dxProcessIslands(StepUtils.java:121) [INFO] at net.java.dev.joode.World.stepEuler(World.java:400) [INFO] at net.java.dev.joode.World.step(World.java:366) [INFO] at org.xith3d.physics.simulation.joode.JoodeSimulationWorld.stepImpl(JoodeSimulationWorld.java:243) [INFO] at org.xith3d.physics.simulation.SimulationWorld.step(SimulationWorld.java:517) [INFO] at org.xith3d.physics.simulation.SimulationEngine.step(SimulationEngine.java:173) [INFO] at org.xith3d.physics.simulation.SimulationEngine.update(SimulationEngine.java:204) [INFO] at org.xith3d.physics.PhysicsEngine.update(PhysicsEngine.java:146) [INFO] at org.xith3d.base.Xith3DEnvironment.updatePhysicsEngine(Xith3DEnvironment.java:151) [INFO] at org.xith3d.loop.RenderLoop.prepareNextFrame(RenderLoop.java:680) [INFO] at org.xith3d.loop.RenderLoop.loopIteration(RenderLoop.java:728) [INFO] at org.xith3d.loop.RenderLoop.update(RenderLoop.java:788) [INFO] at org.xith3d.loop.UpdatingThread.nextIteration(UpdatingThread.java:473) [INFO] at org.xith3d.loop.RenderLoop.nextIteration(RenderLoop.java:817) [INFO] at org.xith3d.loop.RenderLoop.loop(RenderLoop.java:852) [INFO] at org.xith3d.loop.UpdatingThread.run(UpdatingThread.java:526) [INFO] at org.xith3d.loop.RenderLoop.run(RenderLoop.java:875) [INFO] at java.lang.Thread.run(Unknown Source) [INFO] ------------------------------------------------------------------------
|
|
|
|
« Last Edit: 14. July 2009, 03:44:30 pm by Marvin Fröhlich »
|
Logged
|
|
|
|
Marvin Fröhlich
Xith Lord
Administrator
Guru
   
Offline
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #1 on: 14. July 2009, 03:47:19 pm » |
|
Could you please use the current SVN trunk and try again? the last binary download is outdated.
Marvin
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #2 on: 24. July 2009, 10:05:50 am » |
|
Hi Marvin,
I try the get the trunk version running. But I have a small issue.
org.jagatoo.datatypes.Sized2iRO is missing in the jagatoo.jar as supplied in the trunk. Or must I change my code?
With best regards,
|
|
|
|
|
Logged
|
|
|
|
Marvin Fröhlich
Xith Lord
Administrator
Guru
   
Offline
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #3 on: 24. July 2009, 03:57:14 pm » |
|
If you're using Eclipse, open the affected class and press CTRL+SHIFT+O. This will reorganize your imports and will automatically add the missing ones. The class, you're talking about, has been moved to the OpenMaLi project.
Marvin
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #4 on: 27. July 2009, 09:57:32 am » |
|
Hi, Even with the trunk version, the assert still occurs. Below the source code how to reproduce this situation is attached. I had to update the code to get it running with the trunk version. Did I forgot something, or is it a bug? With best regards: The source: package org.prt.simulator;
import java.util.ArrayList;
import org.jagatoo.input.InputSystem; import org.jagatoo.input.devices.components.Key; import org.jagatoo.input.events.KeyPressedEvent; import org.jagatoo.input.events.KeyReleasedEvent; import org.openmali.types.twodee.Sized2iRO; import org.openmali.vecmath2.Colorf; import org.openmali.vecmath2.Matrix3f; import org.openmali.vecmath2.Point3f; import org.openmali.vecmath2.Tuple3f; import org.openmali.vecmath2.Vector3f; import org.xith3d.base.Xith3DEnvironment; import org.xith3d.loop.CanvasFPSListener; import org.xith3d.loop.InputAdapterRenderLoop; import org.xith3d.loop.opscheduler.OperationScheduler; import org.xith3d.physics.PhysicsEngine; import org.xith3d.physics.PhysicsGFXManager; import org.xith3d.physics.collision.CollideableGroup; import org.xith3d.physics.collision.CollisionEngine; import org.xith3d.physics.collision.CollisionResolver; import org.xith3d.physics.collision.collideable.BoxCollideable; import org.xith3d.physics.collision.collideable.PlaneCollideable; import org.xith3d.physics.joode.JoodePhysicsEngine; import org.xith3d.physics.simulation.Body; import org.xith3d.physics.simulation.SimulationEngine; import org.xith3d.physics.simulation.SimulationWorld; import org.xith3d.render.Canvas3D; import org.xith3d.render.Canvas3DFactory; import org.xith3d.render.config.CanvasConstructionInfo; import org.xith3d.render.config.DisplayMode.FullscreenMode; import org.xith3d.scenegraph.BranchGroup; import org.xith3d.ui.hud.HUD; import org.xith3d.ui.hud.widgets.Label; import org.xith3d.ui.text2d.TextAlignment;
/** * Simulator class. Simple simulator for PRT. Can be extended in the near * future. Used units are in S.I. units (meters etc.) */ public class Simulator extends InputAdapterRenderLoop { private PhysicsEngine physicsEngine; private ArrayList<Body> movingObjects = new ArrayList<Body>(); private ArrayList<Point3f> originalPositions = new ArrayList<Point3f>(); private ArrayList<Vector3f> originalVelocities = new ArrayList<Vector3f>(); private RobotBody robotBody;
// Definitions private final float fieldWidth = 6.0f; private final float fieldLength = 9.0f; private final float halfFieldWidth = this.fieldWidth / 2.0f; private final float halfFieldLength = this.fieldLength / 2.0f; private final int robotCount = 6; // at least 1 private float linearVelocity = 1.0f; float angle = 0.0f; float MAX_LINEAR_VELOCITY = 6.0f;
@Override public void onKeyPressed(KeyPressedEvent e, Key key) {
switch (key.getKeyID()) { case NUMPAD_ADD: linearVelocity = Math.min(this.linearVelocity * 1.05f, MAX_LINEAR_VELOCITY); System.out.println("key +: linear velocity set to " + linearVelocity); break; case NUMPAD_SUBTRACT: linearVelocity = Math.max(linearVelocity / 1.05f, 0); System.out.println("key -: linear velocity set to " + linearVelocity); break; case _0: case NUMPAD0: linearVelocity = 0.0f; robotBody.getBody().setLinearVelocity(0.0f, 0.0f, 0.0f); robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("0: everything stopped"); break; case BACK_SPACE: robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("BS: rotation stopped"); break;
case UP: if (this.physicsEngine.isEnabled()) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getDirection().mul(this.robotBody.getSpeed()); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } else { this.physicsEngine.setEnabled(true); } System.out.println("Key UP: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case DOWN: if (this.physicsEngine.isEnabled()) { float speed = this.robotBody.getSpeed(); if (speed > 0.0f) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getBody().getLinearVelocity().mul(.5f); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } } else { this.physicsEngine.setEnabled(true); } System.out.println("Key DOWN: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case LEFT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() + 2.0f * (float) Math.PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; case RIGHT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() - 2.0f * (float) Math.PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; } }
@Override public void onKeyReleased(KeyReleasedEvent e, Key key) { switch (key.getKeyID()) { case SPACE: if (this.physicsEngine.isEnabled()) { for (int i = 0; i < this.movingObjects.size(); i++) { final Body body = this.movingObjects.get(i); Tuple3f pos = this.originalPositions.get(i); body.setPosition(pos); Vector3f vel = this.originalVelocities.get(i); vel.scale(1f, 1f, 100f); body.setLinearVelocity(vel); // body.resetAngularVelocity(); body.setRotationMatrix(Matrix3f.IDENTITY); } } else { this.physicsEngine.setEnabled(true); } break; case ESCAPE: this.end(); break; } }
private void addMovingObject(Body body) { this.movingObjects.add(body); this.originalPositions.add(new Point3f(body.getPosition())); this.originalVelocities.add(new Vector3f(body.getLinearVelocity())); }
private void setupPhysicsAndScene(Xith3DEnvironment sceneGraph) { // XPAL world creation final PhysicsEngine physEng = new JoodePhysicsEngine(); final CollisionEngine collEng = physEng.getCollisionEngine(); final SimulationEngine simEng = physEng.getSimulationEngine(); final SimulationWorld simWorld = simEng.newWorld();
simWorld.setStepSize(1000L); simWorld.setGravity(0f, -9.81f, 0f);
final PhysicsGFXManager gfxManager = physEng.getGFXManager(); physEng.getDefaultSurfaceParameters().setParameter("mu", 0.2f); final BranchGroup scene = sceneGraph.addPerspectiveBranch().getBranchGroup(); CollideableGroup environment = collEng.newGroup();
// Create field ground PlaneCollideable ground = collEng.newPlane(0f, 1f, 0f, 0f); PlaneCollideable.setDefaultAppearance("grass.jpg"); gfxManager.directAdd(ground, scene); environment.addCollideable(ground);
// Create the falling bricks... Tuple3f ballPos = new Tuple3f(0.0f, 0.0f, 3.0f + 10.0f);
for (int i = 0; i < robotCount; i++) { Tuple3f robotPos;
if (i == 0) { robotPos = new Tuple3f(ballPos.getX() - 0.175f, ballPos.getY() - 0.1f, 0.05f + 20.0f); } else { robotPos = new Tuple3f( /* x */(i / (float) robotCount) * fieldLength - halfFieldLength, /* y */halfFieldWidth - 0.40f, /* z */0.05f + 10.0f * (i + 1) / robotCount); } Body robot = createRobot(collEng, simWorld, gfxManager, scene, environment, robotPos, "Robot" + Integer.toString(i));
// Add collision resolvers for this robot // i.e. one collision resolver for each previously created moving object (ball, other robots) for (Body movingObject : this.movingObjects) { if (movingObject != robot) { physEng.addCollisionResolver(new CollisionResolver(robot, movingObject)); } }
if (i == 1) { robot.setLinearVelocity((i % 2) / 5.0f, (i % 3) / 3.0f, 0.0f); } } String robotName = movingObjects.get(1).getName() + " (selected)"; movingObjects.get(1).setName(robotName); // 0 is ball; 1 is first robot robotBody = new RobotBody(movingObjects.get(1), physEng);
physEng.addCollisionResolver(new CollisionResolver(environment));
physEng.setEnabled(false); sceneGraph.setPhysicsEngine(physEng); this.physicsEngine = physEng;
}
private Body createRobot(final CollisionEngine collEng, final SimulationWorld simWorld, final PhysicsGFXManager gfxManager, final BranchGroup scene, CollideableGroup environment, Tuple3f position, String name) { BoxCollideable.setDefaultAppearance("crate.png"); BoxCollideable robot = collEng.newBox(0.75f, 0.10f, 0.35f); Body body = simWorld.newBody();
Tuple3f simPos = convertRc2Sim(position.getX(), position.getY(), position.getZ() + robot.getSize().getZ() + 0.01f); body.setMass(20.0f); body.setPosition(simPos); body.addCollideable(robot); body.setName(name);
simWorld.addBody(body); scene.addChild(gfxManager.add(robot)); environment.addCollideable(robot); addMovingObject(body);
System.out.println("Lin. vel. robot=" + body.getLinearVelocity().getX()); System.out.println("Lin. vel. moving object (robot)=" + movingObjects.get(movingObjects.size() - 1).getLinearVelocity().getX());
return body; }
private HUD createInfoHUD(Sized2iRO size, OperationScheduler opScheder) { HUD hud = new HUD(size, 800f);
Label info = new Label(hud.getResX(), 40f, "Press SPACE to (re-)start the simulation.", Colorf.WHITE, TextAlignment.CENTER_LEFT); info.setPadding((int) 10f); hud.getContentPane().addWidget( info, 0f, hud.getResY() - info.getHeight() );
return (hud); }
public Simulator(CanvasConstructionInfo canvasInfo) throws Exception { super(128f); System.out.println("Hit SPACE to start/reset the simulation, or ESC to exit"); Xith3DEnvironment env = new Xith3DEnvironment(5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f, this);
setupPhysicsAndScene(env); env.addHUD(createInfoHUD(canvasInfo.getDisplayMode(), getOperationScheduler()));
Canvas3D canvas = Canvas3DFactory.create(canvasInfo); env.addCanvas(canvas); this.addFPSListener(new CanvasFPSListener(canvas)); // get an impression of how fast we are simulating
// enable external inputs - keyboard command InputSystem.getInstance().registerNewKeyboardAndMouse( canvas.getPeer() ); this.begin(TimingMode.MICROSECONDS);
}
static Tuple3f convertRc2Sim(float x, float y, float z) { return new Tuple3f(x, z, y); }
public static void main(String[] args) throws Exception { new Simulator(new CanvasConstructionInfo(FullscreenMode.WINDOWED, true, "RoboCup Simulator")); }
public class RobotBody { private Body body = null; private float speed = MAX_LINEAR_VELOCITY;
public RobotBody(Body body, PhysicsEngine physEng) { this.body = body; }
public float getSpeed() { return speed; }
public void setSpeed(float speed) { this.speed = speed; }
public Vector3f getDirection() { Vector3f dir = body.getLinearVelocity(); dir.setY(0.0f); // not interested in vertical speed
if (Float.isNaN(dir.length()) || dir.length() < .001) { if (Float.isNaN(angle)) { angle = 0.0f; } dir = new Vector3f((float) Math.cos(angle), 0.0f, (float) Math.cos(angle)); } else { angle = body.getRotationY(); if (Float.isNaN(angle)) { angle = 0.0f; body.setRotation(0, 0, 0); } } dir.normalize(); return dir; }
public Body getBody() { return this.body; } } }
Output: [INFO] Hit SPACE to start/reset the simulation, or ESC to exit [INFO] Initializing JOODE...ok [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] Lin. vel. robot=0.0 [INFO] Lin. vel. moving object (robot)=0.0 [INFO] java.lang.AssertionError: 3.490448E-4 [INFO] at net.java.dev.joode.stepper.lcp.BaraffLCPFixedStatic.driveInToRange(BaraffLCPFixedStatic.java:272) [INFO] at net.java.dev.joode.stepper.lcp.BaraffLCPFixedStatic.computeForces(BaraffLCPFixedStatic.java:153) [INFO] at net.java.dev.joode.stepper.EulerStepper.step(EulerStepper.java:400) [INFO] at net.java.dev.joode.stepper.StepUtils.dxProcessIslands(StepUtils.java:121) [INFO] at net.java.dev.joode.World.stepEuler(World.java:400) [INFO] at net.java.dev.joode.World.step(World.java:366) [INFO] at org.xith3d.physics.simulation.joode.JoodeSimulationWorld.stepImpl(JoodeSimulationWorld.java:243) [INFO] at org.xith3d.physics.simulation.SimulationWorld.step(SimulationWorld.java:554) [INFO] at org.xith3d.physics.simulation.SimulationEngine.step(SimulationEngine.java:184) [INFO] at org.xith3d.physics.simulation.SimulationEngine.update(SimulationEngine.java:220) [INFO] at org.xith3d.physics.PhysicsEngine.update(PhysicsEngine.java:146) [INFO] at org.xith3d.base.Xith3DEnvironment.updatePhysicsEngine(Xith3DEnvironment.java:166) [INFO] at org.xith3d.loop.RenderLoop.prepareNextFrame(RenderLoop.java:591) [INFO] at org.xith3d.loop.RenderLoop.loopIteration(RenderLoop.java:638) [INFO] at org.xith3d.loop.RenderLoop.update(RenderLoop.java:698) [INFO] at org.xith3d.loop.UpdatingThread.nextIteration(UpdatingThread.java:473) [INFO] at org.xith3d.loop.RenderLoop.nextIteration(RenderLoop.java:709) [INFO] at org.xith3d.loop.RenderLoop.loop(RenderLoop.java:762) [INFO] at org.xith3d.loop.UpdatingThread.run(UpdatingThread.java:526) [INFO] at org.xith3d.loop.RenderLoop.run(RenderLoop.java:785) [INFO] at org.xith3d.loop.RenderLoop.begin(RenderLoop.java:841) [INFO] at org.xith3d.loop.RenderLoop.begin(RenderLoop.java:863) [INFO] at org.prt.simulator.Simulator.<init>(Simulator.java:289) [INFO] at org.prt.simulator.Simulator.main(Simulator.java:298)
|
|
|
|
« Last Edit: 27. July 2009, 05:34:01 pm by Marvin Fröhlich »
|
Logged
|
|
|
|
Marvin Fröhlich
Xith Lord
Administrator
Guru
   
Offline
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #5 on: 27. July 2009, 06:10:14 pm » |
|
Hmm... works for me. Though I don't see, that the simulation simulates  . Maybe you should ask the ODE/JOODE guys over at JGO, what that assertion has to say. It looks like a JOODE internal issue. I have applied some very minor changes to your code. Maybe you want to have a look at them. You can do a simple text compare. public class Simulator extends InputAdapterRenderLoop { private PhysicsEngine physicsEngine; private ArrayList<Body> movingObjects = new ArrayList<Body>(); private ArrayList<Point3f> originalPositions = new ArrayList<Point3f>(); private ArrayList<Vector3f> originalVelocities = new ArrayList<Vector3f>(); private RobotBody robotBody;
// Definitions private final float fieldWidth = 6.0f; private final float fieldLength = 9.0f; private final float halfFieldWidth = this.fieldWidth / 2.0f; private final float halfFieldLength = this.fieldLength / 2.0f; private final int robotCount = 6; // at least 1 private float linearVelocity = 1.0f; private float angle = 0.0f; private static final float MAX_LINEAR_VELOCITY = 6.0f;
@Override public void onKeyPressed(KeyPressedEvent e, Key key) {
switch (key.getKeyID()) { case NUMPAD_ADD: linearVelocity = Math.min(this.linearVelocity * 1.05f, MAX_LINEAR_VELOCITY); System.out.println("key +: linear velocity set to " + linearVelocity); break; case NUMPAD_SUBTRACT: linearVelocity = Math.max(linearVelocity / 1.05f, 0); System.out.println("key -: linear velocity set to " + linearVelocity); break; case _0: case NUMPAD0: linearVelocity = 0.0f; robotBody.getBody().setLinearVelocity(0.0f, 0.0f, 0.0f); robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("0: everything stopped"); break; case BACK_SPACE: robotBody.getBody().setAngularVelocity(0.0f, 0.0f, 0.0f); System.out.println("BS: rotation stopped"); break;
case UP: if (this.physicsEngine.isEnabled()) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getDirection().mul(this.robotBody.getSpeed()); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } else { this.physicsEngine.setEnabled(true); } System.out.println("Key UP: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case DOWN: if (this.physicsEngine.isEnabled()) { float speed = this.robotBody.getSpeed(); if (speed > 0.0f) { Vector3f newLinearVelocity = (Vector3f) this.robotBody.getBody().getLinearVelocity().mul(.5f); this.robotBody.getBody().setLinearVelocity(newLinearVelocity); } } else { this.physicsEngine.setEnabled(true); } System.out.println("Key DOWN: speed:" + this.robotBody.getBody().getLinearVelocity().length() + ", direction: " + this.robotBody.getDirection().toString()); break; case LEFT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() + FastMath.TWO_PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; case RIGHT: if (this.physicsEngine.isEnabled()) { float newRotation = this.robotBody.getBody().getRotationY() - FastMath.TWO_PI / 16.0f; if (Float.isNaN(newRotation)) { newRotation = 0.0f; } this.robotBody.getBody().setRotationY(newRotation); angle = newRotation; } else { this.physicsEngine.setEnabled(true); } System.out.println(String.format("Key left: velocity angle set to %f", this.robotBody.getBody() .getRotationY())); break; } }
@Override public void onKeyReleased(KeyReleasedEvent e, Key key) { switch (key.getKeyID()) { case SPACE: if (this.physicsEngine.isEnabled()) { for (int i = 0; i < this.movingObjects.size(); i++) { final Body body = this.movingObjects.get(i); Point3f pos = this.originalPositions.get(i); body.setPosition(pos); Vector3f vel = this.originalVelocities.get(i); vel.scale(1f, 1f, 100f); body.setLinearVelocity(vel); // body.resetAngularVelocity(); body.setRotationMatrix(Matrix3f.IDENTITY); } } else { this.physicsEngine.setEnabled(true); } break; case ESCAPE: this.end(); break; } }
private void addMovingObject(Body body) { this.movingObjects.add(body); this.originalPositions.add(new Point3f(body.getPosition())); this.originalVelocities.add(new Vector3f(body.getLinearVelocity())); }
private void setupPhysicsAndScene(Xith3DEnvironment sceneGraph) { // XPAL world creation final PhysicsEngine physEng = new JoodePhysicsEngine(); final CollisionEngine collEng = physEng.getCollisionEngine(); final SimulationEngine simEng = physEng.getSimulationEngine(); final SimulationWorld simWorld = simEng.newWorld();
simWorld.setStepSize(1000L); simWorld.setGravity(0f, -9.81f, 0f);
final PhysicsGFXManager gfxManager = physEng.getGFXManager(); physEng.getDefaultSurfaceParameters().setParameter("mu", 0.2f); final BranchGroup scene = sceneGraph.addPerspectiveBranch().getBranchGroup(); CollideableGroup environment = collEng.newGroup();
// Create field ground PlaneCollideable ground = collEng.newPlane(0f, 1f, 0f, 0f); PlaneCollideable.setDefaultAppearance("grass.jpg"); gfxManager.directAdd(ground, scene); environment.addCollideable(ground);
// Create the falling bricks... Point3f ballPos = new Point3f(0.0f, 0.0f, 3.0f + 10.0f);
for (int i = 0; i < robotCount; i++) { Point3f robotPos;
if (i == 0) { robotPos = new Point3f(ballPos.getX() - 0.175f, ballPos.getY() - 0.1f, 0.05f + 20.0f); } else { robotPos = new Point3f( /* x */(i / (float) robotCount) * fieldLength - halfFieldLength, /* y */halfFieldWidth - 0.40f, /* z */0.05f + 10.0f * (i + 1) / robotCount); } Body robot = createRobot(collEng, simWorld, gfxManager, scene, environment, robotPos, "Robot" + Integer.toString(i));
// Add collision resolvers for this robot // i.e. one collision resolver for each previously created moving object (ball, other robots) for (Body movingObject : this.movingObjects) { if (movingObject != robot) { physEng.addCollisionResolver(new CollisionResolver(robot, movingObject)); } }
if (i == 1) { robot.setLinearVelocity((i % 2) / 5.0f, (i % 3) / 3.0f, 0.0f); } } String robotName = movingObjects.get(1).getName() + " (selected)"; movingObjects.get(1).setName(robotName); // 0 is ball; 1 is first robot robotBody = new RobotBody(movingObjects.get(1), physEng);
physEng.addCollisionResolver(new CollisionResolver(environment));
physEng.setEnabled(false); sceneGraph.setPhysicsEngine(physEng); this.physicsEngine = physEng;
}
private Body createRobot(final CollisionEngine collEng, final SimulationWorld simWorld, final PhysicsGFXManager gfxManager, final BranchGroup scene, CollideableGroup environment, Point3f position, String name) { BoxCollideable.setDefaultAppearance("crate.png"); BoxCollideable robot = collEng.newBox(0.75f, 0.10f, 0.35f); Body body = simWorld.newBody();
Point3f simPos = convertRc2Sim(position.getX(), position.getY(), position.getZ() + robot.getSize().getZ() + 0.01f); body.setMass(20.0f); body.setPosition(simPos); body.addCollideable(robot); body.setName(name);
simWorld.addBody(body); scene.addChild(gfxManager.add(robot)); environment.addCollideable(robot); addMovingObject(body);
System.out.println("Lin. vel. robot=" + body.getLinearVelocity().getX()); System.out.println("Lin. vel. moving object (robot)=" + movingObjects.get(movingObjects.size() - 1).getLinearVelocity().getX());
return body; }
private HUD createInfoHUD(Sized2iRO size) { HUD hud = new HUD(size, 800f);
Label info = new Label(hud.getResX(), 40f, "Press SPACE to (re-)start the simulation.", Colorf.WHITE, TextAlignment.CENTER_LEFT); info.setPadding(10); hud.getContentPane().addWidget( info, 0f, hud.getResY() - info.getHeight() );
return (hud); }
public Simulator(BasicApplicationArguments arguments) throws Throwable { super(128f); System.out.println("Hit SPACE to start/reset the simulation, or ESC to exit"); Xith3DEnvironment env = new Xith3DEnvironment(5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f, this);
ResourceLocator resLoc = TestUtils.createResourceLocator(); resLoc.createAndAddTSL("textures"); setupPhysicsAndScene(env); env.addHUD(createInfoHUD(arguments.getResolution()));
Canvas3D canvas = Canvas3DFactory.create(arguments.getCanvasConstructionInfo(), "RoboCup Simulator"); env.addCanvas(canvas); this.addFPSListener(new CanvasFPSListener(canvas)); // get an impression of how fast we are simulating canvas.addWindowClosingListener(new WindowClosingRenderLoopEnder(this)); // enable external inputs - keyboard command InputSystem.getInstance().registerNewKeyboardAndMouse( canvas.getPeer() ); }
static Point3f convertRc2Sim(float x, float y, float z) { return new Point3f(x, z, y); }
public static void main(String[] args) throws Throwable { Simulator test = new Simulator(Xith3DTest.parseCommandLine(args)); test.begin(); }
public class RobotBody { private Body body = null; private float speed = MAX_LINEAR_VELOCITY;
public RobotBody(Body body, PhysicsEngine physEng) { this.body = body; }
public float getSpeed() { return speed; }
public void setSpeed(float speed) { this.speed = speed; }
public Vector3f getDirection() { Vector3f dir = body.getLinearVelocity(); dir.setY(0.0f); // not interested in vertical speed
if (Float.isNaN(dir.length()) || dir.length() < .001) { if (Float.isNaN(angle)) { angle = 0.0f; } dir = new Vector3f(FastMath.cos(angle), 0.0f, FastMath.cos(angle)); } else { angle = body.getRotationY(); if (Float.isNaN(angle)) { angle = 0.0f; body.setRotation(0, 0, 0); } } dir.normalize(); return dir; }
public Body getBody() { return this.body; } } }
Oh and btw. You shouldn't use the InputAdapterRenderLoop. It is just for testing purposes. Use the plain RenderLoop and implement a KeyboardListener in a separate class. This is much cleaner for a custom application. (Maybe I should move the InputAdapterRenderLoop class to the xith-tk source tree.) Marvin
|
|
|
|
« Last Edit: 27. July 2009, 06:12:26 pm by Marvin Fröhlich »
|
Logged
|
|
|
|
roslamir
Enjoying the stay
Offline
Posts: 50
|
 |
« Reply #6 on: 28. July 2009, 01:04:23 am » |
|
Marvin, Oh and btw. You shouldn't use the InputAdapterRenderLoop. It is just for testing purposes. Use the plain RenderLoop and implement a KeyboardListener in a separate class. This is much cleaner for a custom application. I am using it too since that's how XIN tells us to do it.  Roslan
|
|
|
|
|
Logged
|
|
|
|
Marvin Fröhlich
Xith Lord
Administrator
Guru
   
Offline
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #7 on: 28. July 2009, 11:31:20 am » |
|
I am using it too since that's how XIN tells us to do it.  I am pretty sure, it doesn't. The testcases use it to keep it short and all in one class. I will check XIN. At least it shouldn't tell you to use it. Marvin
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #8 on: 29. July 2009, 06:37:38 pm » |
|
Hi, I posted my issue on the ODE users group. I received the following answer from Tilmann Zaeschke ----------------------------------------------------- Date: Wed, 29 Jul 2009 14:18:23 +0200 Local: Wed, Jul 29 2009 2:18 pm Subject: Re: [ode-users] Assertion error in stepper.lcp.BaraffLCPFixedStatic.driveInTo I don't think JOODE is still used, the last update was in 2006. But you could use www.ode4j.org instead, that is based on ode 0.11.1. Unfortunately, there is no support for OPCODE/GIMPACT as of now. Cheers, Tilmann ----------------------------------------------------- Should Xith3d not start to use ode4j ? It seems to be more active than JOODE. Cheers, Jürge
|
|
|
|
|
Logged
|
|
|
|
Marvin Fröhlich
Xith Lord
Administrator
Guru
   
Offline
Posts: 4381
May the 4th, be with you...
|
 |
« Reply #9 on: 29. July 2009, 09:58:04 pm » |
|
My last info is, that Tom is working on JOODE again, tough with limited time effort. So it is still active, but a little bit behind the scenes. I wuold like to write an XPAL implementation for JBullet. But I have no time for it. On the other hand Tom is working to merge JBullets best into the JOODE source. So JOODE might bot be the worst choise after all.
Marvin
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #10 on: 31. July 2009, 07:05:34 pm » |
|
Hi Marvin,
I understand that you would wait for JBullet integration in JOODE. Till that time my problem will not be disappear. I will try an second attempt on the ODE list....
With best regards,
Jürge
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #11 on: 19. August 2009, 09:02:32 pm » |
|
Hi,
My problem also occur in the example "BoxDropTest". When I enable asserts and run the example "BoxDropTest" with recent version the assert occur. (I took this example as basis for my simulator).
With best regards,
Jurge
|
|
|
|
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #12 on: 19. August 2009, 09:14:24 pm » |
|
The assert also occur in example: "HingeJointTest2".
Some background info: My application retrieved NaN's from the linear velocity, rotation and direction for bodies (after a few movements). Which made the simulator output useless. To investigate this problem I enabled the asserts.
REMARK: HingeJointTest2 and HingeJointTest are almost identical. HingeJointTest2 is using a CollidableGroup and a CollisionResolver.
|
|
|
|
« Last Edit: 20. August 2009, 06:08:06 pm by Jurge »
|
Logged
|
|
|
|
Jurge
Just dropped in
Offline
Posts: 11
|
 |
« Reply #13 on: 27. August 2009, 06:42:21 am » |
|
I did some further investigation.
The issue occur when running org.xith3d.test.physics.BoxDropTest with asserts enabled. If only the line physEng.getDefaultSurfaceParameters().setParameter( "mu", 10f ); is changed to physEng.getDefaultSurfaceParameters().setParameter( "mu", 0.f );
Then the issue is disappeared, but objects don't have friction anymore.
|
|
|
|
|
Logged
|
|
|
|
t_larkworthy
Just dropped in
Offline
Posts: 15
|
 |
« Reply #14 on: 27. August 2009, 12:58:48 pm » |
|
Hello, yeah the error you are getting is to do with numerical errors //check the change in acceleration remains 0 throughout the pivot assert isZero(da.m[cNormal.get(i)]) : da.m[cNormal.get(i)]; da.m[cNormal.get(i)] = 0; //adjust for numerical erors, it *should* be zero after fdir
Basically, the pivot step in the LCP should keep certain variable constant (change of 0). But rounding errors means some don't, and instead they are reported as having a *tiny* change. I can see that I wrote code to make the ones that should be zero zero regardless. anyway the isZero check uses BaraffLCPFixedStatic.TOLERANCE. Which by default is .0001f. You are going just over this tolerance. The TOLERANCE variable is publicly modifiable, so just change that to .001 instead. Clearly we should up the default value slightly. Tom
|
|
|
|
|
Logged
|
|
|
|
|