C# Simulation Programming - Bind robot entity (C#)


1. Prepare SPL simulation script
  1. In this C# project, below simulation script will be used to generate sim state file named "boxsim.xml".

      
    StartSimulationEngine  "SimState/basicsim.xml"
    
    
    AddNewEntity    wall1  	/Position:-0.5  0.25  -2.5
    AddBoxShape  	/Dimensions:3.0  0.5  0.5  	/Mass:1.0	/Texture:"WoodFloor.jpg"
    
    AddNewEntity    wall2  	/Position:-0.5  0.25  2.5
    AddBoxShape  	/Dimensions:3.0  0.5  0.5  	/Mass:1.0	/Texture:"WoodFloor.jpg"
    
    AddNewEntity    wall3  	/Position:-2.5  0.25  0
    AddBoxShape  	/Dimensions:0.5  0.5  4.5  	/Mass:1.0	/Texture:"WoodFloor.jpg"
    
    AddNewEntity    wall4  	/Position:2.5  0.25  0
    AddBoxShape  	/Dimensions:0.5  0.5  4.5  	/Mass:1.0	/Texture:"WoodFloor.jpg"
    
    
    
    AddDifferentialDriveEntity    myrobot
    
    AddBumperEntity    bumper1	/ParentEntity:myrobot
    	/FrontPosition:0    0.1    -0.3
    	/RearPosition:0    0.1    0.3
    
    AddLaserRangeFinderEntity    lrf1	/Position:0  0.4  0	/ParentEntity:myrobot
    
    FlushScript  
    
    wait 10000
    SaveSceneAs    "SimState/boxsim.xml"  
    
      


  2. Save script.

  3. Press "F5" key or click "Run" icon.

  4. This script will generate sim state file named "boxsim.xml" under the "SimState" directory.



2. Download and open C# project file
  1. Download source code.

    SimulationFromState2.zip


  2. Unzip downloaded file under the MSRDS installation folder.

  3. Open "DSS Command Prompt" from the MSRDS windows menu and execute "DssProjectMigration.exe" for the unzipped folder.

      
    dssprojectmigration "here_your_unzipped_folder_name"	
    
      



3. C# source code for SimulationFromState2.proj
  1. SimulationFromState2.cs

      
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.Ccr.Core;
    using Microsoft.Dss.Core;
    using Microsoft.Dss.Core.Attributes;
    using Microsoft.Dss.ServiceModel.Dssp;
    using Microsoft.Dss.ServiceModel.DsspServiceBase;
    using W3C.Soap;
    using System.IO;
    
    using dssp = Microsoft.Dss.ServiceModel.Dssp;
    using engineproxy = Microsoft.Robotics.Simulation.Engine.Proxy;
    using submgr = Microsoft.Dss.Services.SubscriptionManager;
    using simengine = Microsoft.Robotics.Simulation.Engine;
    using physics = Microsoft.Robotics.Simulation.Physics;
    
    using Microsoft.Robotics.Simulation;
    using Microsoft.Robotics.Simulation.Engine;
    using Microsoft.Robotics.Simulation.Physics;
    using Microsoft.Robotics.PhysicalModel;
    
    
    namespace SimulationFromState2
    {
    	[Contract(Contract.Identifier)]
    	[DisplayName("SimulationFromState2")]
    	[Description("SimulationFromState2 service (no description provided)")]
    	class SimulationFromState2Service : DsspServiceBase
    	{        
            simengine.SimulationEnginePort _notificationTarget;
    
            DifferentialDriveEntity _robot = null;
    
    		[ServiceState]
    		SimulationFromState2State _state = new SimulationFromState2State();
    		
    		[ServicePort("/SimulationFromState2", AllowMultipleInstances = true)]
    		SimulationFromState2Operations _mainPort = new SimulationFromState2Operations();
    		
    		public SimulationFromState2Service(DsspServiceCreationPort creationPort)
    			: base(creationPort)
    		{
    		}
    
            protected override void Start()
            {
                _notificationTarget = new simengine.SimulationEnginePort();
    
                base.Start();
    
                MainPortInterleave.CombineWith(
                    new Interleave(
                        new TeardownReceiverGroup(),
                        new ExclusiveReceiverGroup(
                            Arbiter.Receive(true, _notificationTarget, InsertEntityNotificationHandler),
                            Arbiter.Receive(true, _notificationTarget, DeleteEntityNotificationHandler)                        
                        ),
                        new ConcurrentReceiverGroup()
                    )
                );
    
    
                //Start simulation engine from the state file
                string filename = "SimState/boxsim.xml";
    
                dssp.PartnerType pt = new dssp.PartnerType();
                System.Xml.XmlQualifiedName qName = 
                	new System.Xml.XmlQualifiedName("StateService", "http://schemas.microsoft.com/xw/2004/10/dssp.html");
                pt.Name = qName;
                pt.Service = filename;
                pt.Contract = "http://schemas.microsoft.com/robotics/2006/04/simulationengine.html";
    
                engineproxy.Contract.CreateService(ConstructorPort, new PartnerType[] { pt });
    
    
                //Request to robot platform bilding
                simengine.EntitySubscribeRequestType esrt = new simengine.EntitySubscribeRequestType();
                esrt.Name = "myrobot";
                simengine.SimulationEngine.GlobalInstancePort.Subscribe(esrt, _notificationTarget);
            }
    
    
    
            void InsertEntityNotificationHandler(simengine.InsertSimulationEntity ins)
            {           
                if (ins.Body.State.Name == "myrobot")
                {
                    _robot = (DifferentialDriveEntity)ins.Body;
    
                    LogInfo(LogGroups.Console, _robot.State.Name + " was connected!");                
                }
            }
            
    
            void DeleteEntityNotificationHandler(simengine.DeleteSimulationEntity del)
            {
                if (del.Body.State.Name == "myrobot")
                {
                    _robot = null;
                }
            }          
    	}    
    }
    
    
      


  2. SimulationFromState2Types.cs

      
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.Ccr.Core;
    using Microsoft.Dss.Core.Attributes;
    using Microsoft.Dss.ServiceModel.Dssp;
    using Microsoft.Dss.ServiceModel.DsspServiceBase;
    using W3C.Soap;
    
    namespace SimulationFromState2
    {
    	public sealed class Contract
    	{
    		[DataMember]
    		public const string Identifier = "http://schemas.tempuri.org/2009/12/simulationfromstate2.html";
    	}
    	
    	[DataContract]
    	public class SimulationFromState2State
    	{
    	}
    	
    	[ServicePort]
    	public class SimulationFromState2Operations : PortSet
    	{
    	}
    	
    	public class Get : Get>
    	{
    		public Get()
    		{
    		}
    		
    		public Get(GetRequestType body)
    			: base(body)
    		{
    		}
    		
    		public Get(GetRequestType body, PortSet responsePort)
    			: base(body, responsePort)
    		{
    		}
    	}
    }
    
    
      



4. Execute C# project
  1. Press "F5" key to run sample code.