Courageous

I am trying to build a piston like actuator. To begin with I used the KukaLBR3Arm entity code and modified it to my use. I have created a single joint between two box entities that will act like a piston. When I am running the simulation, it gives me a NullReferenceException error. Can somebody please help me, find the error I spent the whole weekend in figuring out the error. Thank you.

And also if you notice just above the public class ActuatorEntity : VisualEntity

I haven't added

[DataContract]

[CLSCompliant(true)]

Since whenever I have this and compile my code it gives me:

Warning 1 'Robotics.Actuation.ActuatorEntity' cannot be marked as CLS-compliant because the assembly does not have a CLSCompliant attribute C:\Microsoft Robotics Studio 1.5 (CTP May 2007)\samples\SimulationTutorials\BoxActuation\BoxActuator.cs 39 6 Actuation

Can somebody please help me and tell me what am I doing wrong. Thank you.


Code Snippet

using System;

using System.Collections.Generic;

using System.Text;

using xna = Microsoft.Xna.Framework;

using xnagrfx = Microsoft.Xna.Framework.Graphics;

using xnaprof = Microsoft.Robotics.Simulation.MeshLoader;

using Microsoft.Dss.Core.Attributes;

#region Simulation namespaces

using simcommonproxy = Microsoft.Robotics.Simulation.Proxy;

using simcommon = Microsoft.Robotics.Simulation;

using Microsoft.Robotics.Simulation.Engine;

using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;

using Microsoft.Robotics.Simulation.Physics;

using arm = Microsoft.Robotics.Services.ArticulatedArm.Proxy;

using W3C.Soap;

using Microsoft.Robotics.PhysicalModel;

using physicalmodelproxy = Microsoft.Robotics.PhysicalModel.Proxy;

using System.ComponentModel;

using Microsoft.Robotics.Simulation;

using Microsoft.Ccr.Core;

#endregion

namespace Robotics.SampleActuator

{

public class ActuatorEntity : VisualEntity

{

#region Variables and Constants

const float ARM_MASS = 1f;

const float ARM_THICKNESS = 0.03f;

const float ARM_LENGTH = 0.075f;

const float DELTA = 0.000f;

float ARM_LENGTH2 = ARM_LENGTH + ARM_THICKNESS * 2;

float MIDPOINT_Y = ARM_LENGTH / 2f + ARM_THICKNESS;

const int _jointCount = 1;

#endregion

[DataMember]

public int JointCount

{

get { return _jointCount; }

}

List<Joint> _joints = new List<Joint>();

[DataMember]

public List<Joint> Joints

{

get { return _joints; }

set { _joints = value; }

}

List<ArmLinkEntity> _links = new List<ArmLinkEntity>();

#region Constructors

// Default constructor

public ActuatorEntity()

{

}

public ActuatorEntity(Vector3 position)

{

State.Pose.Position = position;

PhysicsJoint jointInstance = null;

JointLinearProperties commonLinear = new JointLinearProperties();

commonLinear.XMotionMode = JointDOFMode.Free;

commonLinear.MotionLimit = new JointLimitProperties(0, 0, new SpringProperties(50000, 100000, 0));

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

// joints must be names

jointInstance.State.Name = "Joint";

Joints.Add(jointInstance);

if (_baseLink == null)

{

//programmatically build articulated arm

CreateBase(_joints[0]);

CreateArm(_joints[0]);

}

//Set physics shape on each child entity

_links[0].CapsuleShape = new CapsuleShape(

new CapsuleShapeProperties(ARM_MASS,

new Pose(new Vector3(0, MIDPOINT_Y, 0)),

ARM_THICKNESS,

ARM_LENGTH));

//set a lower joint for the arm

ArmLinkEntity link = _links[0] as ArmLinkEntity;

link.LowerJoint = _joints[0];

//set the entity name in upper connector

link.LowerJoint.State.Connectors[0].Entity = link;

}

#endregion

#region Link creation

ArmLinkEntity _baseLink;

[DataMember]

public ArmLinkEntity BaseLink

{

get { return _baseLink; }

set { _baseLink = value; }

}

void CreateBase(Joint joint)

{

PhysicsJoint commonJoint = (PhysicsJoint)joint;

float mass = 1;

float radius = 0.03f;

CapsuleShape baseShape = new CapsuleShape(new CapsuleShapeProperties(mass,

new Pose(new Vector3(0, radius + 0.015f / 2, 0)),

radius, 0.015f));

// create connect point for base. Top and center of its shape.

commonJoint.State.Connectors[0] = new EntityJointConnector(null,

new Vector3(0, 0, 1),

new Vector3(0, 1, 0), // joint rotates around the Y(vertical axis)

new Vector3(0, baseShape.CapsuleState.Radius * 2 + baseShape.CapsuleState.Dimensions.Y, 0));

ArmLinkEntity link = new ArmLinkEntity("base",

"lbr3_j0.obj",

new Pose(new Vector3(0, -radius - 0.005f, 0),

TypeConversion.FromXNA(xna.Quaternion.CreateFromAxisAngle(new xna.Vector3(0, 1, 0), 0))));

link.State.Pose.Position = State.Pose.Position;

link.UpperJoint = commonJoint;

_baseLink = link;

_baseLink.CapsuleShape = baseShape;

_links.Add(link);

}

ArmLinkEntity _armLink;

[DataMember]

public ArmLinkEntity ArmLink

{

get { return _armLink; }

set { _armLink = value; }

}

void CreateArm(Joint joint)

{

PhysicsJoint commonJoint = (PhysicsJoint)joint;

commonJoint.State.Connectors[1] = new EntityJointConnector(null,

new Vector3(0, 0, 1),

new Vector3(0, 1, 0),

new Vector3(0, 0, 0));

ArmLinkEntity link = new ArmLinkEntity("arm",

"lbr3_j1.obj",

new Pose(new Vector3(0, -MIDPOINT_Y, 0),

TypeConversion.FromXNA(xna.Quaternion.CreateFromAxisAngle(new xna.Vector3(0, 1, 0), 0))));

link.State.Pose.Position = State.Pose.Position;

_armLink = link;

_links.Add(link);

}

#endregion

#region Initialize

//Override the base Preserialize method so that we can properly serialize joints

public override void PreSerialize()

{

base.PreSerialize();

PrepareJointsForSerialization();

}

//Override the base PostDeserialize method so that we can fix-up our joint links

public override void PostDeserialize()

{

base.PostDeserialize();

Dictionary<string, Entity> entities;

Dictionary<string, Joint> joints;

RestoreJointConnectivity(out entities, out joints);

// _links is not serialized, rebuild it

_links = new List<ArmLinkEntity>();

_links.Add(_baseLink);

_links.Add(_armLink);

}

//Initialization

public override void Initialize(xnagrfx.GraphicsDevice device, PhysicsEngine physicsEngine)

{

try

{

InitError = string.Empty;

//Initialize will load the graphics mesh

base.Initialize(device, physicsEngine);

foreach (VisualEntity c in _links)

{

c.Parent = this;

c.Initialize(device, physicsEngine);

}

//Insert the joints into the simulation, which initializes and activates them

physicsEngine.InsertJoint((PhysicsJoint)_joints[0]);

//Compute the bounding sphere

xna.Vector3 center = xna.Vector3.Zero;

float radius = Math.Max(0, ARM_LENGTH2 * (_links.Count - 2));

EntityBoundingSphere = new xna.BoundingSphere(center, radius);

}

catch (Exception ex)

{

HasBeenInitialized = false;

InitError = ex.ToString();

}

}

#endregion

#region Update

//Frame update. Also calls update on all child links

public override void Update(FrameUpdate update)

{

base.Update(update);

//Update arm position & orientation if different from the entity's

if (SimulationEngine.GlobalInstance.SimulatorMode == SimulationEngine.SimModeType.Edit)

{

// Update positions if necessary (if user translates)

if (Position - _baseLink.Position != xna.Vector3.Zero)

{

xna.Vector3 offset = Position - _baseLink.Position;

//be careful about this loop statement

foreach (ArmLinkEntity link in _links)

{

link.Position += offset;

}

_baseLink.Position = Position;

}

// Update orientations if necesary (if user orients)

xna.Quaternion orientationOffset = TypeConversion.ToXNA(State.Pose.Orientation) -

TypeConversion.ToXNA(_baseLink.State.Pose.Orientation);

if (orientationOffset.LengthSquared() > .00001f)

// != new xna.Quaternion(0, 0, 0, 0)), precision problem

{

// Compute the rotation amount

xna.Quaternion rotation = TypeConversion.ToXNA(State.Pose.Orientation) *

xna.Quaternion.Inverse(

TypeConversion.ToXNA(_baseLink.State.Pose.Orientation));

// -translation * rotation * translation => affine transform

// Use this to update position

xna.Matrix transform = xna.Matrix.CreateTranslation(-Position) *

xna.Matrix.CreateFromQuaternion(rotation) *

xna.Matrix.CreateTranslation(Position);

// be careful about this loops

for (int i = 1; i < _links.Count; ++i)

{

// Compute new position & orientation for the new pose

xna.Vector3 position = (TypeConversion.ToXNA(_links[i].State.Pose.Position));

position = (xna.Vector3.Transform(position, transform));

xna.Quaternion orientation = TypeConversion.ToXNA(_links[i].State.Pose.Orientation);

orientation = rotation * orientation;

Pose newPose = new Pose(TypeConversion.FromXNA(position), TypeConversion.FromXNA(orientation));

_links[i].State.Pose = newPose;

_links[i].PhysicsEntity.SetPose(newPose);

}

// Assign orientation directly to avoid precision error

_baseLink.State.Pose.Orientation = State.Pose.Orientation;

_baseLink.PhysicsEntity.SetPose(State.Pose);

}

}

//be careful about this loop

foreach (ArmLinkEntity link in _links)

{

link.Update(update);

}

}

#endregion

#region Render

//Frame Render.

public override void Render(Microsoft.Xna.Framework.Graphics.GraphicsDevice device, MatrixTransforms transforms, CameraEntity currentCamera)

{

base.Render(device, transforms, currentCamera);

foreach (ArmLinkEntity link in _links)

{

link.Render(device, transforms, currentCamera);

}

}

public void SetJointTargetOrientation(Joint j, AxisAngle axisAngle)

{

Task<Joint, AxisAngle> deferredTask = new Task<Joint, AxisAngle>(j, axisAngle, SetJointTargetOrientationInternal);

DeferredTaskQueue.Post(deferredTask);

}

public void SetJointTargetPose(Joint j, Pose pose)

{

Task<Joint, Pose> deferredTask = new Task<Joint, Pose>(j, pose, SetJointTargetPoseInternal);

DeferredTaskQueue.Post(deferredTask);

}

public void SetJointTargetVelocity(Joint j, Vector3 velocity)

{

Task<Joint, Vector3> deferredTask = new Task<Joint, Vector3>(j, velocity, SetJointTargetVelocityInternal);

DeferredTaskQueue.Post(deferredTask);

}

void SetJointTargetPoseInternal(Joint j, Pose pose)

{

if (j.State.Linear != null)

{

((PhysicsJoint)j).SetLinearDrivePosition(pose.Position);

}

if (j.State.Angular != null)

{

((PhysicsJoint)j).SetAngularDriveOrientation(pose.Orientation);

}

}

void SetJointTargetOrientationInternal(Joint j, AxisAngle axisAngle)

{

if (j.State.Angular != null)

{

// the physics engine doesn't deal well with axis angles in the range -2*Pi to -Pi

// and Pi to 2*Pi. Work around this problem by adjusting the angle to the range -Pi to Pi

// and then map the angle to the range 2*Pi to 3*Pi if positive and -2*Pi to -3*Pi if negative.

// This seems to get the physics engine to do the right thing.

float fullRotation = (float)(2 * Math.PI);

while (axisAngle.Angle < -Math.PI)

axisAngle.Angle += fullRotation;

while (axisAngle.Angle > Math.PI)

axisAngle.Angle -= fullRotation;

if (axisAngle.Angle < 0.0f)

axisAngle.Angle -= fullRotation;

else

axisAngle.Angle += fullRotation;

Quaternion target =

TypeConversion.FromXNA(

xna.Quaternion.CreateFromAxisAngle(TypeConversion.ToXNA(axisAngle.Axis), axisAngle.Angle)

);

((PhysicsJoint)j).SetAngularDriveOrientation(target);

}

}

void SetJointTargetVelocityInternal(Joint j, Vector3 velocity)

{

if (j.State.Linear != null)

{

((PhysicsJoint)j).SetLinearDriveVelocity(velocity);

}

else

{

((PhysicsJoint)j).SetAngularDriveVelocity(velocity);

}

}

public override void Dispose()

{

// dispose the joints

foreach (PhysicsJoint joint in _joints)

{

PhysicsEngine.DeleteJoint(joint);

}

// we must dispose our children

foreach (ArmLinkEntity link in _links)

{

link.Dispose();

}

base.Dispose();

}

#endregion

}

}



Re: Microsoft Robotics - Simulation Piston like actuator

Chris Kilner

Hi Courageous,

To get rid of the CLS error, add the following to your AssemblyInfo.cs

[assembly: CLSCompliant(true)]

To avoid the null reference, I have found that it is sometimes neccesary to define the first connector twice, though I can't tell you why.

So, try redefining commonJoint.State.Connectors[0] in CreateArm.

Hope this helps,

Chris





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

Thanks Chris for your help. But I modified the whole code and borrowed some of the code Alan Oursland used for his Simple pendulum. So far I am able to run the simulation and see the two boxes. Here is the code.

Code Snippet

using Microsoft.Ccr.Core;

using Microsoft.Dss.Core;

using Microsoft.Dss.Core.Attributes;

using Microsoft.Dss.ServiceModel.Dssp;

using Microsoft.Dss.ServiceModel.DsspServiceBase;

using System;

using System.Collections.Generic;

using System.Security.Permissions;

using System.ComponentModel;

using System.Xml;

using actuation = Robotics.Actuation;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Robotics.Simulation.Physics;

using Microsoft.Robotics.PhysicalModel;

using xna = Microsoft.Xna.Framework;

using xnagrfx = Microsoft.Xna.Framework.Graphics;

using xnaprof = Microsoft.Robotics.Simulation.MeshLoader;

using System.IO;

using System.Drawing;

#region Simulation namespaces

using simcommonproxy = Microsoft.Robotics.Simulation.Proxy;

using simcommon = Microsoft.Robotics.Simulation;

using Microsoft.Robotics.Simulation.Engine;

using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;

using Microsoft.Robotics.Simulation.Physics;

using arm = Microsoft.Robotics.Services.ArticulatedArm.Proxy;

using W3C.Soap;

using Microsoft.Robotics.PhysicalModel;

using physicalmodelproxy = Microsoft.Robotics.PhysicalModel.Proxy;

using System.ComponentModel;

using Microsoft.Robotics.Simulation;

#endregion

namespace Robotics.Actuation

{

[DataContract]

//[CLSCompliant(true)]

public class JointEntity : VisualEntity

{

private PhysicsJoint _joint = null;

private SingleShapeEntity _parentBox;

private SingleShapeEntity _childBox;

private Vector3 _parentPosition;

[DataMember]

public Joint Joint

{

get { return _joint; }

set { _joint = (PhysicsJoint)value; }

}

[DataMember]

public SingleShapeEntity ParentBox

{

get { return _parentBox; }

set { _parentBox = value; }

}

[DataMember]

public SingleShapeEntity ChildBox

{

get { return _childBox; }

set { _childBox = value; }

}

private const float radius = 0.05f;

private const float length = 0.20f;

private const float mass = 10.0f;

public JointEntity()

{

}

public JointEntity(Vector3 initialPosition)

{

base.State.Pose.Position = initialPosition;

}

private void CreateJoint()

{

//JointAngularProperties commonAngular = new JointAngularProperties();

//commonAngular.TwistMode = JointDOFMode.Free;

JointLinearProperties commonLinear = new JointLinearProperties();

SpringProperties jointSpringProperties = new SpringProperties(500, 0, 0);

commonLinear.MotionLimit = new JointLimitProperties(0, 1000, jointSpringProperties);

commonLinear.XMotionMode = JointDOFMode.Free;

commonLinear.ZMotionMode = JointDOFMode.Free;

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

// Vector3 velocity = new Vector3(0, 0, 1);

//_joint.SetLinearDriveVelocity(velocity);

_joint.State.Name = "Joint";

_joint.State.EnableCollisions = true;

}

private void CreateSupport(Vector3 pos)

{

BoxShapeProperties prop = new BoxShapeProperties(

"supportbox",

mass,

new Pose(new Vector3(0, 0, 0)),

new Vector3(length, length, length));

Shape shape = new BoxShape(prop);

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

_parentBox.State.MassDensity.Mass = 1.0f;

_parentBox.State.Name = "parentBox";

_parentBox.State.Pose.Position = new Vector3(pos.X + 0f, pos.Y + 0.1f, pos.Z + 0f);

}

private void CreateChildBox(Vector3 pos)

{

BoxShapeProperties prop = new BoxShapeProperties(

"ChildBox",

mass,

new Pose(new Vector3(0, 0, 0)),

new Vector3(length, length, length));

Shape shape = new BoxShape(prop);

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

_childBox.State.Name = "ChildBox";

_childBox.State.MassDensity.Mass = 1.0f;

_childBox.State.Pose.Position = new Vector3(pos.X + 0f, pos.Y + 0.1f, pos.Z + 0.2f);

//PhysicsEntity.Create(shape);

//shape.ApplyForceAtLocalPosition(new Vector3(0, 0, 100), new Vector3(pos.X + 0f, pos.Y + 0.1f, pos.Z + 0.2f));

}

public override void Initialize(xnagrfx.GraphicsDevice device, PhysicsEngine physicsEngine)

{

try

{

InitError = string.Empty;

// connect joint

if (_joint == null)

{

CreateJoint();

}

else

{

_joint = PhysicsJoint.Create(_joint.State);

}

if (_parentBox == null) CreateSupport(base.State.Pose.Position);

if (_childBox == null) CreateChildBox(base.State.Pose.Position);

// initialize will load the graphics mesh

base.Initialize(device, physicsEngine);

_parentBox.Initialize(device, physicsEngine);

_childBox.Initialize(device, physicsEngine);

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

_parentBox,

new Vector3(0, 1, 0),

new Vector3(0, 0, 1),

new Vector3(0f, 0f, 0f)

);

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

_childBox,

new Vector3(0, 1, 0),

new Vector3(0, 0, 1),

//new Vector3(0f, length / 2 - radius / 2, radius / 2)

new Vector3(0, 0, 0)

);

_parentBox.PhysicsEntity.IsKinematic = true;

PhysicsEngine.InsertJoint(_joint);

Flags |= VisualEntityProperties.DoCompletePhysicsShapeUpdate;

}

catch (Exception ex)

{

HasBeenInitialized = false;

InitError = ex.ToString();

}

}

public override void Update(FrameUpdate update)

{

base.Update(update);

_parentBox.Update(update);

_childBox.Update(update);

_parentBox.PhysicsEntity.IsKinematic = true;

_childBox.PhysicsEntity.IsKinematic = true;

Vector3 velocity = new Vector3(0, 0, 10);

// Be able to give the joint a velocity

((PhysicsJoint)_joint).SetLinearDriveVelocity(velocity);

((PhysicsJoint)_joint).UpdateState();

}

public override void Render(Microsoft.Xna.Framework.Graphics.GraphicsDevice device, MatrixTransforms transforms, CameraEntity currentCamera)

{

base.Render(device, transforms, currentCamera);

_parentBox.Render(device, transforms, currentCamera);

_childBox.Render(device, transforms, currentCamera);

}

public override void Dispose()

{

base.Dispose();

_parentBox.Dispose();

_childBox.Dispose();

}

}

}

And this is the actual project file in which I am creating a JointEntity object.

Code Snippet

using Microsoft.Ccr.Core;

using Microsoft.Dss.Core;

using Microsoft.Dss.Core.Attributes;

using Microsoft.Dss.ServiceModel.Dssp;

using Microsoft.Dss.ServiceModel.DsspServiceBase;

using System;

using System.Collections.Generic;

using System.Security.Permissions;

using System.ComponentModel;

using System.Xml;

using actuation = Robotics.Actuation;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Robotics.Simulation.Physics;

using Microsoft.Robotics.PhysicalModel;

using xna = Microsoft.Xna.Framework;

using xnagrfx = Microsoft.Xna.Framework.Graphics;

using xnaprof = Microsoft.Robotics.Simulation.MeshLoader;

#region Simulation namespaces

using simcommonproxy = Microsoft.Robotics.Simulation.Proxy;

using simcommon = Microsoft.Robotics.Simulation;

using Microsoft.Robotics.Simulation.Engine;

using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;

using Microsoft.Robotics.Simulation.Physics;

using arm = Microsoft.Robotics.Services.ArticulatedArm.Proxy;

using W3C.Soap;

using Microsoft.Robotics.PhysicalModel;

using physicalmodelproxy = Microsoft.Robotics.PhysicalModel.Proxy;

using System.ComponentModel;

using Microsoft.Robotics.Simulation;

#endregion

namespace Robotics.Actuation

{

/// <summary>

/// Implementation class for Actuation

/// </summary>

[DisplayName("Actuation")]

[Description("The Actuation Service")]

[Contract(Contract.Identifier)]

public class ActuationService : DsspServiceBase

{

// partner attribute will cause simulation engine service to start

[Partner("Engine",

Contract = engineproxy.Contract.Identifier,

CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]

private engineproxy.SimulationEnginePort _engineServicePort = new engineproxy.SimulationEnginePort();

// port for interacting with the simulated arm service

arm.ArticulatedArmOperations _armServicePort;

/// <summary>

/// _state

/// </summary>

private ActuationState _state = new ActuationState();

/// <summary>

/// _main Port

/// </summary>

[ServicePort("/actuation", AllowMultipleInstances=false)]

private ActuationOperations _mainPort = new ActuationOperations();

/// <summary>

/// Default Service Constructor

/// </summary>

public ActuationService(DsspServiceCreationPort creationPort) :

base(creationPort)

{

}

/// <summary>

/// Service Start

/// </summary>

/// <summary>

/// Get Handler

/// </summary>

/// <param name="get"></param>

/// <returns></returns>

[ServiceHandler(ServiceHandlerBehavior.Concurrent)]

public virtual IEnumerator<ITask> GetHandler(Get get)

{

get.ResponsePort.Post(_state);

yield break;

}

protected override void Start()

{

base.Start();

// orient sim camera view point

SetupCamera();

// Add objects (entities) in our simulated world

PopulateWorld();

}

private void SetupCamera()

{

// Set up initial view

CameraView view = new CameraView();

view.EyePosition = new Vector3(1.8f, 1, -1);

view.LookAtPoint = new Vector3(0, 0, 0);

SimulationEngine.GlobalInstancePort.Update(view);

}

private void PopulateWorld()

{

AddSky();

AddGround();

AddEntity();

}

#region Environment Entities

void AddSky()

{

// Add a sky using a static texture. We will use the sky texture

// to do per pixel lighting on each simulation visual entity

SkyEntity sky = new SkyEntity("sky.dds", "sky_diff.dds");

SimulationEngine.GlobalInstancePort.Insert(sky);

// Add a directional light to simulate the sun.

LightSourceEntity sun = new LightSourceEntity();

sun.State.Name = "Sun";

sun.Type = LightSourceEntityType.Directional;

sun.Color = new Vector4(0.8f, 0.8f, 0.8f, 1);

sun.Direction = new Vector3(-1.0f, -1.0f, 0.5f);

SimulationEngine.GlobalInstancePort.Insert(sun);

}

void AddGround()

{

// create a large horizontal plane, at zero elevation.

HeightFieldEntity ground = new HeightFieldEntity(

"simple ground", // name

"03RamieSc.dds", // texture image

new MaterialProperties("ground",

0.2f, // restitution

0.5f, // dynamic friction

0.5f) // static friction

);

SimulationEngine.GlobalInstancePort.Insert(ground);

}

void AddEntity()

{

Vector3 initialPosition = new Vector3(0, 0, 0);

JointEntity actuator = new JointEntity(initialPosition);

actuator.State.Name = "Actuator";

SimulationEngine.GlobalInstancePort.Insert(actuator);

}

#endregion

}

}

If you notice in my JointEntity class I have given my joint some SpringProperties. I want the joint to act as a spring between the two boxes.

Here is a simple figure.

______ ______

| Box 1 | ---/////////////////////------| Box 2 |

----------- ^ -----------

|

spring

But when I start the simulation, I just see the two boxes and not the spring. My questions are:-

1. Is there a way we can see the spring in the simulation environment

2. How can I apply a force on one of the boxes so that I am able to mobilize the whole system

3. Will the spring act the way a normal spring works when a force is applied on one end and released i.e. will there be a restoring force on the spring

4. Is there a way I can have a dashboard in my simulation through which I can apply

different magnitudes of force on any of the box and simulate how the system reacts in its environment

Please, if anybody knows an answer to even one of these questions do please help me out. Thank you.





Re: Microsoft Robotics - Simulation Piston like actuator

Stanlo

1. Unless you add a special entity yourself to visualize this, there's nothing currently in either the simulator or Ageia's rendering to draw a joint like that.

2. You'll need to apply the force to all objects in the system.

3. Ageia supports restoring forces as well as dampening. Check the SpringProperties of the joint.

4. The SimpleDashboard used in the tutorials is a win forms service. You can see how the simple dashboard was implemented in the \samples\misc\SimpleDashboard directory.





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

Thanks Stanlo for your help. I just started with no. 2, I applied force on the whole system too but it doesn't work. Here is the code for it.

I added the last three lines to my original code. Please help.

Code Snippet

void AddEntity()

{

Vector3 initialPosition = new Vector3(0, 0, 0);

JointEntity actuator = new JointEntity(initialPosition);

actuator.State.Name = "Actuator";

SimulationEngine.GlobalInstancePort.Insert(actuator);

Vector3 force = new Vector3(0, 0, 5);

Vector3 forcePosition = new Vector3(0, 0, 0.2f);

actuator.PhysicsEntity.ApplyForceAtLocalPosition(force, forcePosition);

}





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

I clicked on the "Go to the definition" for the SpringProperties class and the class doesn't contain a method or a variable for controlling the Spring Restitution (spring restoring force). I also tried plugging different numbers for the damperCoefficient but I am unable to see any noticable movement of the system. Please help.

Thank you.

Code Snippet

using Microsoft.Dss.Core.Attributes;

using System;

using System.ComponentModel;

namespace Microsoft.Robotics.PhysicalModel

{

// Summary:

// Spring coefficients

[DataContract]

public class SpringProperties

{

// Summary:

// Damping coefficient

[Description("The spring damping setting.")]

[DataMember]

public float DamperCoefficient;

//

// Summary:

// Position, on the vertical axis, of the spring rest point. If the spring,

// at rest and there is no deformation, this should be set to zero

[Description(@"Position, on the vertical axis, of the spring rest position.

If the spring is at rest and there is no deformation, this should be set to zero.")]

[DataMember]

public float EquilibriumPosition;

//

// Summary:

// Spting stiffness

[Description("The spring stiffness setting.")]

[DataMember]

public float SpringCoefficient;

// Summary:

// Default constructor

public SpringProperties();

//

// Summary:

// Initialization constructor

//

// Parameters:

// springCoefficient:

//

// damperCoefficient:

//

// equilibriumPosition:

public SpringProperties(float springCoefficient, float damperCoefficient, float equilibriumPosition);

}

}





Re: Microsoft Robotics - Simulation Piston like actuator

George Chrysanthakopoulos

the changes to the spring properties will only take effect when restart your simulation. Our editor does not currently call all the right physics runtime APIs to effect the changes right away



Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

What I did was that I would go and change the numbers in the project file and rerun the simulation. If it wouldn't work I would close the simulation window and the command prompt window and then change the numbers which was followed by rebuilding and re-running it.



Re: Microsoft Robotics - Simulation Piston like actuator

KyleJ - MSFT

1. In the JointEntity Update method you set both _parentBox and _childBox to be kinematic. Kinematic means that the physics engine will not move them. I assume that you want one of them (probably the parent) to be stationary while the child moves. If this is the case, don't set the child to be kinematic.

2. You are applying a force to the Actuator entity but this entity doesn't actually contain any shapes. You need to apply the force to the PhycisEntity in either the parent entity or the child entity.

3. The force is only applied one time. The force will only last for a single frame. If you want the force continually applied, you need to call ApplyForce in your update routine each frame.

There may be other issues as well. I wasn't able to compile your code because you didn't include all of your source code.

-Kyle





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

Thank you for your help. I tried all steps 1,2 and 3 you instructed. But for some reason I am getting runtime errors. This is what I am getting:




Re: Microsoft Robotics - Simulation Piston like actuator

KyleJ - MSFT

The exception is being thrown because you are calling _childBox.ApplyForceAtLocalPosition in CreateChildBox() before _childBox has been initialized. Get rid of this call, you don't need it at all.

Also, you are setting _parentBox to be kinematic when you initialize the joint entity but in update, you are setting the parent to be non-kinematic and the child to be kinematic. You want the parent to be kinematic so that it isn't moved by the physics engine but you want the child to be non-kinematic. Remove those two lines from JointEntity.Update().

-Kyle





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

Thank you a lot you saved my day, thank you once again for your help. I still have one more problem. When I use the ApplyForce method to apply force on the _childBox entity, the box keeps moving forever till infinity. Is there a way I can apply the force for some seconds and release it to see if the spring restores to its original position or not. I tried using a for loop that keeps updating for some time and then stops when the condition becomes false but that doesn't work.

Here is what I was trying.

Code Snippet

public override void Update(FrameUpdate update)

{

base.Update(update);

Vector3 force = new Vector3(0, 0, 0.1f);

Vector3 velocity = new Vector3(0, 0, 10);

_parentBox.Update(update);

_childBox.Update(update);

// Be able to give the joint a velocity

((PhysicsJoint)_joint).SetLinearDriveVelocity(velocity);

((PhysicsJoint)_joint).UpdateState();

for( int i = 0; i < 1000000; i++)

_childBox.PhysicsEntity.ApplyForce(force);

}

And here is the modified code without the for loop.

Code Snippet

using Microsoft.Ccr.Core;

using Microsoft.Dss.Core;

using Microsoft.Dss.Core.Attributes;

using Microsoft.Dss.ServiceModel.Dssp;

using Microsoft.Dss.ServiceModel.DsspServiceBase;

using System;

using System.Collections.Generic;

using System.Security.Permissions;

using System.ComponentModel;

using System.Xml;

using actuation = Robotics.Actuation;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Robotics.Simulation.Physics;

using Microsoft.Robotics.PhysicalModel;

using xna = Microsoft.Xna.Framework;

using xnagrfx = Microsoft.Xna.Framework.Graphics;

using xnaprof = Microsoft.Robotics.Simulation.MeshLoader;

using System.IO;

using System.Drawing;

#region Simulation namespaces

using simcommonproxy = Microsoft.Robotics.Simulation.Proxy;

using simcommon = Microsoft.Robotics.Simulation;

using Microsoft.Robotics.Simulation.Engine;

using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;

using Microsoft.Robotics.Simulation.Physics;

using arm = Microsoft.Robotics.Services.ArticulatedArm.Proxy;

using W3C.Soap;

using Microsoft.Robotics.PhysicalModel;

using physicalmodelproxy = Microsoft.Robotics.PhysicalModel.Proxy;

using System.ComponentModel;

using Microsoft.Robotics.Simulation;

#endregion

namespace Robotics.Actuation

{

[DataContract]

//[CLSCompliant(true)]

public class JointEntity : VisualEntity

{

private PhysicsJoint _joint = null;

private SingleShapeEntity _parentBox;

private SingleShapeEntity _childBox;

private Vector3 _parentPosition;

[DataMember]

public Joint Joint

{

get { return _joint; }

set { _joint = (PhysicsJoint)value; }

}

[DataMember]

public SingleShapeEntity ParentBox

{

get { return _parentBox; }

set { _parentBox = value; }

}

[DataMember]

public SingleShapeEntity ChildBox

{

get { return _childBox; }

set { _childBox = value; }

}

private const float radius = 0.05f;

private const float length = 0.20f;

private const float mass = 10.0f;

public JointEntity()

{

}

public JointEntity(Vector3 initialPosition)

{

base.State.Pose.Position = initialPosition;

}

private void CreateJoint()

{

JointLinearProperties commonLinear = new JointLinearProperties();

SpringProperties jointSpringProperties = new SpringProperties(50000000, 150000000, 0);

commonLinear.MotionLimit = new JointLimitProperties(0, 1000, jointSpringProperties);

commonLinear.XMotionMode = JointDOFMode.Free;

commonLinear.ZMotionMode = JointDOFMode.Free;

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

_joint.State.Name = "Joint";

_joint.State.EnableCollisions = true;

}

private void CreateSupport(Vector3 pos)

{

BoxShapeProperties prop = new BoxShapeProperties(

"supportbox",

mass,

new Pose(new Vector3(0, 0, 0)),

new Vector3(length, length, length));

Shape shape = new BoxShape(prop);

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

_parentBox.State.MassDensity.Mass = 1.0f;

_parentBox.State.Name = "parentBox";

_parentBox.State.Pose.Position = new Vector3(pos.X + 0f, pos.Y + 0.1f, pos.Z + 0f);

}

private void CreateChildBox(Vector3 pos)

{

BoxShapeProperties prop = new BoxShapeProperties(

"ChildBox",

mass,

new Pose(new Vector3(0, 0, 0)),

new Vector3(length, length, length));

Shape shape = new BoxShape(prop);

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

_childBox.State.Name = "ChildBox";

_childBox.State.MassDensity.Mass = 1.0f;

_childBox.State.Pose.Position = new Vector3(pos.X + 0f, pos.Y + 0.1f, pos.Z + 0.3f);

}

public override void Initialize(xnagrfx.GraphicsDevice device, PhysicsEngine physicsEngine)

{

try

{

InitError = string.Empty;

// connect joint

if (_joint == null)

{

CreateJoint();

}

else

{

_joint = PhysicsJoint.Create(_joint.State);

}

if (_parentBox == null) CreateSupport(base.State.Pose.Position);

if (_childBox == null) CreateChildBox(base.State.Pose.Position);

// initialize will load the graphics mesh

base.Initialize(device, physicsEngine);

_parentBox.Initialize(device, physicsEngine);

_childBox.Initialize(device, physicsEngine);

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

_parentBox,

new Vector3(0, 1, 0),

new Vector3(0, 0, 1),

new Vector3(0f, 0f, 0f)

);

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

_childBox,

new Vector3(0, 1, 0),

new Vector3(0, 0, 1),

new Vector3(0, 0, 0)

);

// Keeps the _parentBox at a fixed position

_parentBox.PhysicsEntity.IsKinematic = true;

PhysicsEngine.InsertJoint(_joint);

Flags |= VisualEntityProperties.DoCompletePhysicsShapeUpdate;

}

catch (Exception ex)

{

HasBeenInitialized = false;

InitError = ex.ToString();

}

}

public override void Update(FrameUpdate update)

{

base.Update(update);

Vector3 force = new Vector3(0, 0, 0.1f);

Vector3 velocity = new Vector3(0, 0, 10);

_parentBox.Update(update);

_childBox.Update(update);

// Be able to give the joint a velocity

((PhysicsJoint)_joint).SetLinearDriveVelocity(velocity);

((PhysicsJoint)_joint).UpdateState();

_childBox.PhysicsEntity.ApplyForce(force);

}

public override void Render(Microsoft.Xna.Framework.Graphics.GraphicsDevice device, MatrixTransforms transforms, CameraEntity currentCamera)

{

base.Render(device, transforms, currentCamera);

_parentBox.Render(device, transforms, currentCamera);

_childBox.Render(device, transforms, currentCamera);

}

public override void Dispose()

{

base.Dispose();

_parentBox.Dispose();

_childBox.Dispose();

}

}

}





Re: Microsoft Robotics - Simulation Piston like actuator

KyleJ - MSFT

Now, what would be the fun if someone else fixed every bug I'm sure that with a little perseverance, you can track this one down. (one thing that you ought to keep in mind is that Update is called once every frame. A For loop in this method is not going to do you any good. How about a counter that counts how many times you have set the force and stops setting it after you get to a certain count )

-Kyle





Re: Microsoft Robotics - Simulation Piston like actuator

Courageous

Thanks Kyle for your kind help and encouragement. I developed a small code and have been working on it, I am able to build it succesfully and both the command prompt and simulation windows are opening up but nothing inside the simulation window is showing up (see through window) . It is giving me the -- This program is not responding -- error.

I am really sorry to bother you but I really don't know if I am doing some error or there is a problem with the Microsoft Robotics Simulation environment. Thank you.

Code Snippet

public override void Update(FrameUpdate update)

{

base.Update(update);

Vector3 force = new Vector3(0, 0, -0.1f);

_parentBox.Update(update);

_childBox.Update(update);

xna.Vector3 initialPosition = _parentBox.Position;

_parentBox.PhysicsEntity.IsKinematic = true;

_childBox.PhysicsEntity.IsKinematic = false;

while (true)

{

_childBox.PhysicsEntity.ApplyForce(force);

Vector3 zeroVelocity = new Vector3(0, 0, 0);

// if childBox is not moving (velociy is zero) then move parentBox --- trying to compare velocities

if (_childBox.EntityState.Velocity.X == 0 && _childBox.EntityState.Velocity.Y == 0 && _childBox.EntityState.Velocity.Z == 0)

{

_parentBox.PhysicsEntity.IsKinematic = false;

_childBox.PhysicsEntity.IsKinematic = true;

_parentBox.PhysicsEntity.ApplyForce(force);

// if _parentBox has moved a distance of 0.3 stop it and go to the begining of the loop

if (_parentBox.Position.Z == initialPosition.Z + 0.3f )

{

_parentBox.PhysicsEntity.IsKinematic = true;

_childBox.PhysicsEntity.IsKinematic = false;

initialPosition = _parentBox.Position;

}

}

}

}

I am trying to simulate a caterpillar like motion. childBox moves towards the parentBox and stops, the parentBox then moves some distance and stops the childBox then once again moves towards the parentBox and stops. This continues.

  1. Initially # #
  2. child box moves # # then stops
  3. parent box moves # # towards child box then stops
  4. child box moves once again # #
  5. this continues

#: represents a box





Re: Microsoft Robotics - Simulation Piston like actuator

KyleJ - MSFT

The reason the simulation environment is locking up is because you are not allowing it to draw any frames. Update is called each frame. In this method, you update the state or position or force on your entity and then you return. You have a while(true) statement in your Update method which will never return control to the simulator so that it can draw the next frame.

-Kyle