/// <summary> /// Do step method which computes the actual carry postures /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //Set the current avatar state this.simulationState = simulationState; //Create a new result MSimulationResult result = new MSimulationResult() { Events = simulationState.Events ?? new List <MSimulationEvent>(), DrawingCalls = new List <MDrawingCall>(), SceneManipulations = simulationState.SceneManipulations ?? new List <MSceneManipulation>(), Posture = simulationState.Current, Constraints = simulationState.Constraints ?? new List <MConstraint>() }; //Special case for both handed carry if (bothHandedCarry) { this.DoStepBothHanded(result, time, simulationState); } //Single handed carry ->Perform a single handed do step else { result = this.DoStepSingleHanded(result, time, simulationState); } //Return the computed result return(result); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //To do -> Check whether the execution is allowed ReachMMUImpl instance = new ReachMMUImpl { SceneAccess = this.SceneAccess, ServiceAccess = this.ServiceAccess, SkeletonAccess = this.SkeletonAccess }; //Get the min distance parameter if (instruction.Properties != null) { instruction.Properties.GetValue(out minReachDistance, "MinDistance"); instruction.Properties.GetValue(out debug, "Debug"); } //Call the instance responsible for the left/right arm instance.Initialize(this.AvatarDescription, new Dictionary <string, string>()); instance.AssignInstruction(instruction, simulationState); //Add the instructions and the mmu instance instructions.Add(instruction); mmuInstances.Add(instruction, instance); return(new MBoolResponse(true)); }
/// <summary> /// Method to compute a new posture for the next frame /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MSimulationResult DoStep(Double time, MSimulationState simulationState) { //Create a result to store all the computed data MSimulationResult result = new MSimulationResult() { //Just forward the present constraints Constraints = simulationState.Constraints ?? new List <MConstraint>(), Posture = simulationState.Current, SceneManipulations = simulationState.SceneManipulations }; //Execute instructions on main thread this.ExecuteOnMainThread(() => { this.SkeletonAccess.SetChannelData(simulationState.Current); this.AssignPostureValues(simulationState.Current); //this.transform.position = this.SkeletonAccess.GetRootPosition(this.AvatarDescription.AvatarID).ToVector3(); //this.transform.rotation = this.SkeletonAccess.GetRootRotation(this.AvatarDescription.AvatarID).ToQuaternion(); this.animator.Update((float)time); result.Posture = this.GetRetargetedPosture(); }); return(result); }
public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //Create a default result MSimulationResult result = new MSimulationResult() { Events = new List <MSimulationEvent>(), Constraints = simulationState.Constraints ?? new List <MConstraint>(), SceneManipulations = new List <MSceneManipulation>(), Posture = simulationState.Current }; elapsed += (float)time; float blendWeight = Math.Min(1, elapsed / blendDuration); //Perform the actual motion blending result.Posture = MMICSharp.Common.Tools.Blending.PerformBlend(this.SkeletonAccess as IntermediateSkeleton, simulationState.Initial, simulationState.Current, blendWeight, true); //Provide end event if finished if (elapsed >= this.blendDuration) { result.Events.Add(new MSimulationEvent("Blend finished", mmiConstants.MSimulationEvent_End, this.instruction.ID)); } return(result); }
/// <summary> /// Basic do step call /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //Transmit the scene (if first frame-> transmit full scene otherwise just deltas) this.mmuAccess.PushScene(this.transmitFullScene); //Full transmission only required at first frame this.transmitFullScene = false; //Perform the do step of the co-simulation MSimulationResult result = this.coSimulator.DoStep(time, simulationState); //Write the events if (result.Events != null && PrintDebugMessages) { foreach (MSimulationEvent ev in result.Events) { Console.WriteLine("Event: " + ev.Name + " " + ev.Type + " " + ev.Reference); } } //Check the endcondition if (this.CheckEndCondition != null && this.CheckEndCondition(result)) { result.Events.Add(new MSimulationEvent("Finished", mmiConstants.MSimulationEvent_End, this.Instruction.ID)); } return(result); }
public override MSimulationResult DoStep(double time, MSimulationState simulationState) { MSimulationResult result = new MSimulationResult() { Constraints = simulationState.Constraints, Events = simulationState.Events ?? new List <MSimulationEvent>(), Posture = simulationState.Current, SceneManipulations = simulationState.SceneManipulations, DrawingCalls = new List <MDrawingCall>() }; this.elapsed += TimeSpan.FromSeconds(time); //Add a drwaing call result.DrawingCalls.Add(new MDrawingCall(MDrawingCallType.DrawText) { Properties = new Dictionary <string, string>() { { "text", this.text + this.elapsed.TotalSeconds + " s" } } }); //Create the finished event if (this.elapsed > this.duration) { result.Events.Add(new MSimulationEvent("Finished", mmiConstants.MSimulationEvent_End, this.instruction.ID)); } return(result); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState avatarState) { //Initialize the ik service this.ServiceAccess.IKService.Setup(this.AvatarDescription, new Dictionary <string, string>()); //Create a new constraint manager this.constraintManager = new ConstraintManager(this.SceneAccess); //Assign the instruction this.instruction = instruction; //Set state to ik this.state = ReleaseMotionState.IK; this.trajectoryIndex = 0; //Parse the parameters MBoolResponse response = this.ParseParameters(instruction); if (!response.Successful) { return(response); } return(new MBoolResponse(true)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { base.AssignInstruction(instruction, simulationState); //Get the gaze target if (instruction.Properties != null && instruction.Properties.ContainsKey("TargetID")) { this.gazeTarget = this.SceneAccess.GetTransformByID(instruction.Properties["TargetID"]); } else { //Return false if no gaze target is defined return(new MBoolResponse(false) { LogData = new List <string>() { "Error, no gaze target defined" } }); } if (instruction.Properties.ContainsKey("LowerLimit")) { this.lowerLimit = float.Parse(instruction.Properties["LowerLimit"], System.Globalization.CultureInfo.InstalledUICulture); } if (instruction.Properties.ContainsKey("UpperLimit")) { this.upperLimit = float.Parse(instruction.Properties["UpperLimit"], System.Globalization.CultureInfo.InstalledUICulture); } return(new MBoolResponse(true)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { this.instruction = instruction; //Get the carry object (if available) this.carryObject = this.SceneAccess.GetSceneObjectByID(instruction.Properties["TargetID"]); //Add the carry object to the virtual scene this.virtualScene.Apply(new MSceneUpdate() { AddedSceneObjects = new List <MSceneObject>() { carryObject } }, true); //Create a new id for the instruction this.currentInstructionID = MInstructionFactory.GenerateID(); //Create a new subinstruction utilizing the moving target MInstruction subInstruction = new MInstruction(currentInstructionID, "NestedMove", "move") { Properties = PropertiesCreator.Create("TargetID", moveTarget.ID, "SubjectID", instruction.Properties["TargetID"], "Hand", instruction.Properties["Hand"]) }; //Assign the instruction at the co-simulation and create a new wrapper instruction return(this.coSimulator.AssignInstruction(subInstruction, simulationState)); }
/// <summary> /// Method to assign an instruction to the co-simulation /// </summary> /// <param name="instruction"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { this.Instruction = instruction; instruction.Instructions = this.CreateSubInstructions(instruction, simulationState); //Co-simulation internally interprets the instruction and the timing return(this.coSimulator.AssignInstruction(instruction, simulationState)); }
public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //Create a new result MSimulationResult result = new MSimulationResult() { Events = simulationState.Events ?? new List <MSimulationEvent>(), DrawingCalls = new List <MDrawingCall>(), SceneManipulations = simulationState.SceneManipulations ?? new List <MSceneManipulation>(), Posture = simulationState.Current, Constraints = simulationState.Constraints ?? new List <MConstraint>() }; List <MConstraint> constraints = new List <MConstraint>(); //Apply ik if (LeftHandTarget != null) { constraints.Add(new MConstraint(System.Guid.NewGuid().ToString()) { JointConstraint = new MJointConstraint() { GeometryConstraint = new MGeometryConstraint("") { ParentToConstraint = new MTransform(System.Guid.NewGuid().ToString(), LeftHandTarget.Transform.Position, LeftHandTarget.Transform.Rotation), WeightingFactor = 1.0f, }, JointType = MJointType.LeftWrist } }); } if (RightHandTarget != null) { constraints.Add(new MConstraint(System.Guid.NewGuid().ToString()) { JointConstraint = new MJointConstraint() { GeometryConstraint = new MGeometryConstraint("") { ParentToConstraint = new MTransform(System.Guid.NewGuid().ToString(), RightHandTarget.Transform.Position, RightHandTarget.Transform.Rotation), WeightingFactor = 1.0f }, JointType = MJointType.RightWrist }, }); } if (constraints.Count > 0) { MIKServiceResult ikResult = this.ServiceAccess.IKService.CalculateIKPosture(simulationState.Current, constraints, new Dictionary <string, string>()); result.Posture = ikResult.Posture; } return(result); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //Create a new instance of the skeleton access /intermedaite skeleton this.SkeletonAccess = new IntermediateSkeleton(); //Setup the anthropometry this.SkeletonAccess.InitializeAnthropometry(this.AvatarDescription); base.AssignInstruction(instruction, simulationState); //Parse the duration parameter (if defined) bool durationSet = false; float duration = 1f; if (instruction.Properties.ContainsKey("Duration")) { duration = float.Parse(instruction.Properties["Duration"], System.Globalization.CultureInfo.InvariantCulture); } //Parse the angular velocity parameter (if defined) float angularVelocity = 90f; if (instruction.Properties.ContainsKey("AngularVelocity")) { angularVelocity = float.Parse(instruction.Properties["AngularVelocity"], System.Globalization.CultureInfo.InvariantCulture); } bool release = false; //Parse the release parameter (if defined) if (instruction.Properties.ContainsKey("Release")) { release = bool.Parse(instruction.Properties["Release"]); } //If release is not defined -> the handposture is used if (instruction.Properties.ContainsKey("Hand")) { switch (instruction.Properties["Hand"]) { case "Left": this.SetupHand(MJointType.LeftWrist, instruction, duration, angularVelocity, durationSet, release); break; case "Right": this.SetupHand(MJointType.RightWrist, instruction, duration, angularVelocity, durationSet, release); break; } } return(new MBoolResponse(true)); }
/// <summary> /// Basic do step routine that is executed for each frame and generates the actual motion. /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MSimulationResult DoStep(double time, MSimulationState simulationState) { if (this.useIK) { return(this.DoStepIK(time, simulationState)); } else { return(this.DoStepBlending(time, simulationState)); } }
public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //The simulation result which is provided as overall result MSimulationResult result = new MSimulationResult() { Posture = simulationState.Current, Events = new List <MSimulationEvent>(), SceneManipulations = new List <MSceneManipulation>() }; //Handle each active MMU (each instruction coressponds to one MMU) for (int i = instructions.Count - 1; i >= 0; i--) { //Update the simulation state MSimulationResult localResult = mmuInstances[instructions[i]].DoStep(time, simulationState); //Update the simulation state //simulationState.Current = localResult.Posture; //Just forward the constraints simulationState.Constraints = localResult.Constraints; //Write the result result.Constraints = localResult.Constraints; result.Posture = localResult.Posture; //Merge the scene manipulations result.SceneManipulations?.AddRange(localResult.SceneManipulations); //Add the events if (localResult.Events != null && localResult.Events.Count > 0) { result.Events.AddRange(localResult.Events); } //Merge the drawing calls result.DrawingCalls?.AddRange(localResult.DrawingCalls); if (localResult.Events.Exists(s => s.Type == mmiConstants.MSimulationEvent_End && s.Reference == instructions[i].ID)) { //Remove the respective MMU mmuInstances.Remove(instructions[i]); //Remove from the list instructions.RemoveAt(i); } } return(result); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { base.AssignInstruction(instruction, simulationState); this.instruction = instruction; if (instruction.Properties.ContainsKey("BlendDuration")) { this.blendDuration = float.Parse(instruction.Properties["BlendDuration"], System.Globalization.CultureInfo.InvariantCulture); } return(new MBoolResponse(true)); }
/// <summary> /// Computes the root velocity of the avatar /// </summary> /// <param name="time"></param> /// <returns></returns> private float ComputeRootVelocity(double time, MSimulationState simulationState) { //Get the root position this.SkeletonAccess.SetChannelData(simulationState.Initial); var currentRootPosition = this.SkeletonAccess.GetRootPosition(this.AvatarDescription.AvatarID); this.SkeletonAccess.SetChannelData(simulationState.Current); var previousRootPosition = this.SkeletonAccess.GetRootPosition(this.AvatarDescription.AvatarID); previousRootPosition.Y = 0; currentRootPosition.Y = 0; //Estimate the root velocity return(previousRootPosition.Subtract(currentRootPosition).Magnitude() / (float)time); }
/// <summary> /// Basic update routine /// </summary> void Update() { ///Handle the walk command on mouse click if (Input.GetKey(KeyCode.LeftShift) && Input.GetMouseButtonDown(0)) { Vector3 mousePos = Input.mousePosition; Ray mouseRay = Camera.main.ScreenPointToRay(mousePos); RaycastHit hit = new RaycastHit(); if (Physics.Raycast(mouseRay, out hit, 10000)) { //Ray for visual guide from camera to mouse position. Debug.DrawRay(mouseRay.origin, mouseRay.direction * hit.distance, Color.red, 1); GameObject walkTarget = GameObject.Find("WalkTarget"); walkTarget.transform.position = new Vector3(hit.point.x, walkTarget.transform.position.y, hit.point.z); walkTarget.GetComponent <MMISceneObject>().UpdateTransform(); MInstruction walkInstruction = new MInstruction(MInstructionFactory.GenerateID(), "Walk", "Locomotion/Walk") { Properties = PropertiesCreator.Create("TargetName", "WalkTarget", "UseTargetOrientation", false.ToString()) }; MInstruction idleInstruction = new MInstruction(MInstructionFactory.GenerateID(), "Idle", "Pose/Idle") { //Start idle after walk has been finished StartCondition = walkInstruction.ID + ":" + mmiConstants.MSimulationEvent_End //synchronization constraint similar to bml "id:End" (bml original: <bml start="id:End"/> }; //Abort all current tasks this.CoSimulator.Abort(); MSimulationState currentState = new MSimulationState() { Initial = this.avatar.GetPosture(), Current = this.avatar.GetPosture() }; //Assign walk and idle instruction this.CoSimulator.AssignInstruction(walkInstruction, currentState); this.CoSimulator.AssignInstruction(idleInstruction, currentState); } } }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { base.AssignInstruction(instruction, simulationState); if (instruction.Properties.ContainsKey("leftTarget")) { this.LeftHandTarget = this.SceneAccess.GetSceneObjectByID(instruction.Properties["leftTarget"]); } if (instruction.Properties.ContainsKey("rightTarget")) { this.RightHandTarget = this.SceneAccess.GetSceneObjectByID(instruction.Properties["rightTarget"]); } return(new MBoolResponse(true)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //Setup the ik this.ServiceAccess.IKService.Setup(this.AvatarDescription, new Dictionary <string, string>()); //Reset all flags/states this.constraintManager = new ConstraintManager(this.SceneAccess); this.singleShotIK = false; this.singleShotIKTargetPosture = null; //Assign the instruction this.instruction = instruction; //Parse the parameters MBoolResponse result = this.ParseParameters(instruction); if (!result.Successful) { return(result); } //Compute the target posture if (this.singleShotIK) { List <MConstraint> tempConstraints = new List <MConstraint>(); constraintManager.SetConstraints(ref tempConstraints); //Set the ik constraints constraintManager.SetEndeffectorConstraint(this.handJoint, targetTransform.Position, targetTransform.Rotation); //Compute the posture MIKServiceResult ikResult = this.ServiceAccess.IKService.CalculateIKPosture(simulationState.Current, constraintManager.GetJointConstraints(), new Dictionary <string, string>()); this.singleShotIKTargetPosture = ikResult.Posture.Copy(); //Clear the constraints in the constraint manager tempConstraints.Clear(); } //Return true/success return(new MBoolResponse(true)); }
/// <summary> /// Basic do step routine which triggers the simulation update of the repsective MMU /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <param name="mmuID"></param> /// <param name="sessionID"></param> /// <returns></returns> public virtual MSimulationResult DoStep(double time, MSimulationState simulationState, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); //Skip if invalid session result if (!sessionResult.Successful) { return(null); } sessionContent.UpdateLastAccessTime(); //Execute the do step of the respective MMU return(avatarContent.MMUs[mmuID].DoStep(time, simulationState)); }
/// <summary> /// Computes the root velocity of the avatar given the initial and current state /// </summary> /// <param name="time"></param> /// <returns></returns> private float ComputeRootVelocity(double time, MSimulationState simulationState) { float velocity = 0; if (this.rootPositionLastFrame != null) { MVector3 currentRootPosition = new MVector3(simulationState.Initial.PostureData[0], 0, simulationState.Initial.PostureData[2]); //Estimate the root velocity velocity = (rootPositionLastFrame.Subtract(currentRootPosition)).Magnitude() / (float)time; } Console.WriteLine("Root velocity: " + velocity); this.rootPositionLastFrame = new MVector3(simulationState.Initial.PostureData[0], 0, simulationState.Initial.PostureData[2]); return(velocity); }
/// <summary> /// Basic do step call /// </summary> /// <param name="time"></param> /// <param name="simulationState"></param> /// <returns></returns> public override MSimulationResult DoStep(double time, MSimulationState simulationState) { //Transmit the scene (if first frame-> transmit full scene otherwise just deltas) this.mmuAccess.PushScene(this.transmitFullScene); //Full transmission only required at first frame this.transmitFullScene = false; //Perform the do step of the co-simulation MSimulationResult result = this.coSimulator.DoStep(time, simulationState); if (result.Events != null) { foreach (MSimulationEvent ev in result.Events) { Console.WriteLine("Event: " + ev.Name + " " + ev.Type + " " + ev.Reference); } } return(result); }
/// <summary> /// Function is called to control the avatar by using predefined buttons in the GUI. /// </summary> protected virtual void GUIBehaviorInput() { if (GUI.Button(new Rect(10, 10, 120, 50), "Idle")) { MInstruction instruction = new MInstruction(MInstructionFactory.GenerateID(), "Idle", "Pose/Idle"); //MInstruction instruction = new MInstruction(MInstructionFactory.GenerateID(), "MMUTest", "move"); MSimulationState simstate = new MSimulationState(this.avatar.GetPosture(), this.avatar.GetPosture()); this.CoSimulator.Abort(); this.CoSimulator.AssignInstruction(instruction, simstate); } if (GUI.Button(new Rect(140, 10, 120, 50), "Walk to")) { MInstruction walkInstruction = new MInstruction(MInstructionFactory.GenerateID(), "Walk", "Locomotion/Walk") { Properties = PropertiesCreator.Create("TargetID", UnitySceneAccess.Instance.GetSceneObjectByName("WalkTarget").ID) }; MInstruction idleInstruction = new MInstruction(MInstructionFactory.GenerateID(), "Idle", "Pose/Idle") { //Start idle after walk has been finished StartCondition = walkInstruction.ID + ":" + mmiConstants.MSimulationEvent_End //synchronization constraint similar to bml "id:End" (bml original: <bml start="id:End"/> }; this.CoSimulator.Abort(); MSimulationState currentState = new MSimulationState() { Initial = this.avatar.GetPosture(), Current = this.avatar.GetPosture() }; //Assign walk and idle instruction this.CoSimulator.AssignInstruction(walkInstruction, currentState); this.CoSimulator.AssignInstruction(idleInstruction, currentState); this.CoSimulator.MSimulationEventHandler += this.CoSimulator_MSimulationEventHandler; } }
/// <summary> /// Execute command of a MMU /// </summary> /// <param name="instruction"></param> /// <param name="simulationState"></param> /// <param name="hierarchy"></param> /// <param name="mmuID"></param> /// <param name="sessionID"></param> public virtual MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState, string mmuID, string sessionID) { SessionContent sessionContent = null; AvatarContent avatarContent = null; MBoolResponse sessionResult = SessionData.GetContents(sessionID, out sessionContent, out avatarContent); //Directly return if not successfull if (!sessionResult.Successful) { return(sessionResult); } sessionContent.UpdateLastAccessTime(); Logger.Log(Log_level.L_DEBUG, $"Execute instruction {instruction.Name}, {mmuID}"); //Directly assign the instruction return(avatarContent.MMUs[mmuID].AssignInstruction(instruction, simulationState)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //Set elapsed to zero this.elapsed = TimeSpan.Zero; this.instruction = instruction; //Parse the parameters if (instruction.Properties != null) { if (instruction.Properties.ContainsKey(durationKey)) { this.duration = TimeSpan.FromSeconds(double.Parse(instruction.Properties[durationKey])); } if (instruction.Properties.ContainsKey(textKey)) { this.text = instruction.Properties[textKey]; } } return(base.AssignInstruction(instruction, simulationState)); }
public override MBoolResponse AssignInstruction(MInstruction instruction, MSimulationState simulationState) { //To do -> Check whether the execution is allowed MoveMMUImpl instance = new MoveMMUImpl { SceneAccess = this.SceneAccess, ServiceAccess = this.ServiceAccess, SkeletonAccess = this.SkeletonAccess }; //Call the instance responsible for the left/right arm instance.Initialize(this.AvatarDescription, new Dictionary <string, string>()); instance.AssignInstruction(instruction, simulationState); //Add the instructions and the mmu instance instructions.Add(instruction); mmuInstances.Add(instruction, instance); return(new MBoolResponse()); }
/// <summary> /// Updates the transition modeler /// </summary> /// <param name="time"></param> /// <param name="avatarState"></param> /// <returns></returns> public MAvatarPostureValues ComputeResult(float time, MSimulationState avatarState) { //Do nothing if inactive if (!this.Active) { return(avatarState.Current); } //Increment the time this.elapsedTime += time; //Estimate the blend weight -> to do use animation curves float blendWeight = this.WeightFunction(elapsedTime); //Set finished flag if (blendWeight >= 1) { this.Finished = true; } //Perform the blend and return the result return(Blending.PerformBlend(this.Skeleton, this.GetSourcePosture(time, avatarState), this.GetTargetPosture(time, avatarState), blendWeight, this.Mask)); }
public override MSimulationResult DoStep(double time, MSimulationState avatarState) { //Call the remote cosimulation MSimulationResult result = this.remoteCoSimulationMMU.DoStep(time, avatarState); //Fire events if (result != null && result.Events != null && result.Events.Count > 0) { foreach (MSimulationEvent simEvent in result.Events) { this.MSimulationEventHandler?.Invoke(this, simEvent); } } try { this.avatar.AssignPostureValues(result.Posture); } catch (Exception) { Debug.LogError("Problem assigning posture using remote co-simulation"); } return(result); }
public virtual MSimulationResult DoStep(double time, MSimulationState simulationState) { throw new NotImplementedException(); }
/// <summary> /// Returns the boundary constraint for the given instruction /// </summary> /// <param name="instruction"></param> /// <param name="simulationState"></param> /// <returns></returns> public virtual List <MConstraint> GetBoundaryConstraints(MInstruction instruction, MSimulationState simulationState) { return(new List <MConstraint>()); }