Example Using InsertEntity

I want to have two entities inserted into the world where one entity is a child of the other and therefore gets jointed to the parent. I have been able to do this at runtime using the method described in Simulation Tutorial 6, however I can not get it to work programatically. Here is the code I am using:

Code Snippet

Vector3 dimensions =newVector3(1, 1, 1);// meters

SingleShapeEntity parentBox =newSingleShapeEntity(newBoxShape(

newBoxShapeProperties(

100,// mass in kilograms.

newPose(),// relative pose

dimensions)),// dimensions

newVector3(0, 1, 0));

parentBox.State.Name ="ParentBox";

SingleShapeEntity childBox =newSingleShapeEntity(newBoxShape(

newBoxShapeProperties(

100,// mass in kilograms.

newPose(newVector3(0, 1, 0)),// relative pose

dimensions)),// dimensions

newVector3(0, 2, 0));

childBox.State.Name ="ChildBox";

parentBox.InsertEntity(childBox);

SimulationEngine.GlobalInstancePort.Insert(parentBox);

When I run it, I get this initialization error for the childBox:

System.ApplicationException: Physics engine failed to create joint
at Microsoft.Robotics.Simulation.Engine.VisualEntity.CreateAndInsertPhysicsEntity(PhysicsEngine physicsEngine)
at Microsoft.Robotics.Simulation.Engine.SingleShapeEntity.Initialize(GraphicsDevice device, PhysicsEngine physicsEngine)

Does anyone have an example of how to correctly set up the parent/child relationship between these two boxes? Thanks!

[4194 byte] By [KathyChurch] at [2008-1-8]
# 1

It seems that you are using MSRS 1.5, in MSRS 1.5 you'll have to create a joint between the parentbox and the childbox. But if you use MSRS 1.5 (CTP May 2007) then it won't give you any error. Hope this helps, let me know if you need more help.

Courageous

Courageous at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 2

I am using the MSRS 1.5. I was previously attaching pieces together manually with a joint in 1.0, but I was under the impression that in 1.5 that joint was now automatically created for you as in Simulation Tutorial 6. If you could show me an example of a scenario that works correctly, that would be great. Thanks.

KathyChurch at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 3

Here is a sample code whereby I have a linear joint between two boxes, you can also have an angular joint. Let me know if you still need help.

Code Snippet

public class JointEntity : VisualEntity

{

#region Variables and Constants

const float BOX_MASS = 1.0f;

const float BOX_LENGTH = 0.5f;

Vector3 boxDimension = new Vector3(BOX_LENGTH, BOX_LENGTH, BOX_LENGTH);

Vector3 boxPosition1 = new Vector3(0.0f, 0.0f, -1.75f);

Vector3 boxPosition2 = new Vector3(0.0f, 0.0f, 1.75f);

#endregion

#region Joint

private PhysicsJoint _joint = null;

[DataMember]

public Joint Joint

{

get { return _joint; }

set { _joint = (PhysicsJoint)value; }

}

#endregion

#region Boxes

private SingleShapeEntity _box1;

[DataMember]

public SingleShapeEntity Box1

{

get { return _box1; }

set { _box1 = value; }

}

private SingleShapeEntity _box2;

[DataMember]

public SingleShapeEntity Box2

{

get { return _box2; }

set { _box2 = value; }

}

#endregion

#region Create Boxes

private void CreateBox1()

{

BoxShapeProperties property = new BoxShapeProperties(

"Box1",

BOX_MASS,

new Pose(),

boxDimension

);

Shape shape = new BoxShape(property);

_box1 = new SingleShapeEntity(shape, base.State.Pose.Position);

_box1.State.Name = "Box1";

_box1.State.Pose.Position = boxPosition1;

}

private void CreateBox2()

{

BoxShapeProperties property = new BoxShapeProperties(

"Box2",

BOX_MASS,

new Pose(),

boxDimension

);

Shape shape = new BoxShape(property);

_box2 = new SingleShapeEntity(shape, base.State.Pose.Position);

_box2.State.Name = "Box2";

_box2.State.Pose.Position = boxPosition2;

}

#endregion

#region Create Joint

private void CreateJoint()

{

//A linear joint is required for the actuation

JointLinearProperties commonLinear = new JointLinearProperties();

// Create the joint

_joint = PhysicsJoint.Create(new JointProperties(commonLinear, null, null));

// Every entity in MSRS has to have a name, otherwise it will give an error

_joint.State.Name = "Joint";

}

#endregion

#region Constructors

public JointEntity()

{

}

#endregion

#region Initialize

public override void Initialize(GraphicsDevice device, PhysicsEngine physicsEngine)

{

try

{

InitError = string.Empty;

if (_joint == null)

{

CreateJoint();

}

else

{

_joint = PhysicsJoint.Create(_joint.State);

}

if (_box1 == null) CreateBox1();

if (_box2 == null) CreateBox2();

base.Initialize(device, physicsEngine);

_box1.Initialize(device, physicsEngine);

_box2.Initialize(device, physicsEngine);

// Connect the two boxes with a joint |box|-|box|

// Is an array of two, to join a third entity, we'll need to create

// a second joint that connects one of this boxes and the new entity

_joint.State.Connectors[0] = new EntityJointConnector(

_box1, // Connect one end of the joint to box1

new Vector3(0, 0, 1), // normal

new Vector3(0, 1, 0), // axis

new Vector3(0, 0, 0.25f) // connect point

);

_joint.State.Connectors[1] = new EntityJointConnector(

_box2, // Connect the other end of the joint to box2

new Vector3(0, 0, 1), // normal

new Vector3(0, 1, 0), // axis

new Vector3(0, 0, -0.25f) // connect point

);

// Insert the joint

PhysicsEngine.InsertJoint(_joint);

// For handling exceptions

Flags |= VisualEntityProperties.DoCompletePhysicsShapeUpdate;

}

catch(Exception ex)

{

HasBeenInitialized = false;

InitError = ex.ToString();

}

}

#endregion

#region Update

public override void Update(FrameUpdate update)

{

base.Update(update);

_box1.Update(update);

_box2.Update(update);

((PhysicsJoint)_joint).UpdateState();

}

#endregion

#region Render

public override void Render(VisualEntity.RenderMode renderMode, MatrixTransforms transforms, CameraEntity currentCamera)

{

base.Render(renderMode, transforms, currentCamera);

_box1.Render(renderMode, transforms, currentCamera);

_box2.Render(renderMode, transforms, currentCamera);

}

#endregion

#region Dispose

public override void Dispose()

{

base.Dispose();

_box1.Dispose();

_box2.Dispose();

}

#endregion

}

Courageous at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 4

Thank you for posting an example, however it looks like you are manually inserting a joint to connect two unrelated boxes together. I want to use the joint that is automatically created when you add one entity as a child of another. The joint that connects them would be the childBox.ParentJoint in my example.

KathyChurch at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 5

I have tried several things in order to get this to work. I have tried inserting the parent and then inserting the child. I have tried inserting the parent and the child and then setting up the relationship between them afterward. Nothing seems to work. Has anyone else had success getting the automatically generated ParentJoint to work? An example of this would be very helpful. Thanks.

KathyChurch at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 6
Here's some help. Seems that the SingleShapeEntity and the MultiShapeEntity in MSRS 1.5 both fail with the same error. I hassled with this one for days!!! After carefully comparing the BumperArray code in SimulationTutorial2 which works to the MultiShapeEntity code in Entities.cs that does not work, I discovered that there's a subtile difference in their respective Initialization routines. The working code calls base.Initialize() before it calls CreateAndInsertPhysicsEntity() and the failing code is the other way around. So I copied the class definition from Entities.cs into my project and reordered the two lines of code and voila!
Fritzoid at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 7

I have figured out the problem. I am not sure if this is working as intended, but in order to insert an entity as a child of another entity, you must assign it an initial orientation.

Code Snippet

Vector3 dimensions = new Vector3(1, 1, 1); // meters

SingleShapeEntity parentBox = new SingleShapeEntity(new BoxShape(

new BoxShapeProperties(

100, // mass in kilograms.

new Pose(), // relative pose

dimensions)), // dimensions

new Vector3(0, 1, 0));

parentBox.State.Name = "box";

SingleShapeEntity childBox = new SingleShapeEntity(new BoxShape(

new BoxShapeProperties(

100, // mass in kilograms.

new Pose(), // relative pose

dimensions)), // dimensions

new Vector3(0, 2, 0));

childBox.State.Pose.Orientation = new Quaternion(0, 0, 0, 1);

childBox.State.Name = "box[1]";

parentBox.InsertEntity(childBox);

SimulationEngine.GlobalInstancePort.Insert(parentBox);

KathyChurch at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 8

Thank you for finding this bug for us. The problem is that a Quaternion is a struct and so it is initialized, by default, to all 0's. But (0,0,0,0) is an invalid quaternion. In the VisualEntity baseclass Initialize method, we check to see if the Pose Quaternion is invalid and set it to (0,0,0,1) if necessary. If you set a position or a non-default orientation for the child entity, the quaternion in the pose will be initialized correctly, or if you call Initialize before you call CreateAndInsertPhysicsEntity, the pose orientation is initialized correctly. Only in the case where no Pose is specified and CreateAndInsertPhysicsEntity is called before Initialize do you hit this problem.

We'll make sure that it is fixed in the next release. Sorry for the time it took you to track this one down!

-Kyle

KyleJ-MSFT at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 9
I got to work that the joint is created automatically between the two boxes. But how can I adress to the created joint? I want to change the jointProperties. I tried to use the ParentJoint operation, but I got an error:
"System.NullReferenceExeption: Object reference not set to an instance of an object".
the error appears in this line:

childBox.ParentJoint.State.Linear.ZMotionMode = JointDOFMode.Free;

what is wrong? how can I manage this problem?
thanks for your help

Martin_S3 at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 10

This post shows how to change the ParentJoint properties.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2171989&SiteID=1&mode=1

-Kyle

KyleJ-MSFT at 2007-10-2 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...

Microsoft Robotics Studio

Site Classified