Build a Bumper Service

The bumper service is different from the drive, LED, and speaker services because it implements the generic contact sensors contract. The benefit for using the generic contact sensors service is that we need only one class file to represent the bumper service. The amount of code used to represent the bumper service is reduced, and we can use the state variables and DSS operations that are part of the generic contact sensors service. To add the class file, right-click the ARobotServices project, click Add, and then click Class. You can name the new class file ARobotBumper.

Add a Reference

The generic contact sensors service is part of the Robotics.Common assembly. This means you need to add a reference to the Robotics.Common.Proxy assembly using the Add References dialog box. You also need to add namespace references for the ARobot control service and generic contact sensors service. Additionally, you need to add a namespace reference for the subscription manager service because receiving notifications of whisker changes involves creating a subscription. The code for these namespace references is shown as follows:

using arobot = Microsoft.Robotics.Services.ARobot.Proxy;
using bumper = Microsoft.Robotics.Services.ContactSensor.Proxy;
using submgr = Microsoft.Dss.Services.SubscriptionManager;

The namespace for this service is Microsoft.Robotics.Services.ARobot.Bumper. Because we are using the generic contact sensors contract and this comes from another assembly, we need to use the AlternateContract attribute. The attributes listed at the top of the ARobotBumper class should look like the following:

[Contract(Contract.Identifier)]
[AlternateContract(bumper.Contract.Identifier)]
[DisplayName("ARobot Generic Contact Sensor")]
[Description("Provides access to the ARobot whisker used as a
            bumper.
(Uses Generic Contact Sensors contract.)")]

We still need a contract identifier for the ARobotBumper service. This is defined with the following class declaration and added to the top of the ARobotBumper class file:

public sealed class Contract
{
   public const string Identifier =
         "http://custsolutions.net/2007/10/arobotbumper.html";
}

Add Partnerships

The bumper service declares an initial state partner using the InitialStatePartner attribute. This indicates that the generic contact sensors service contains the state used to initialize the bumper service. The code for this declaration is as follows:

[InitialStatePartner(Optional = true)]
private bumper.ContactSensorArrayState _state = new
      bumper.ContactSensorArrayState();

Additionally, we need to declare a main port for the bumper service, as well as ports for the ARobot control service and subscription manager service. The code for these declarations is as follows:

[ServicePort("/ARobotBumper", AllowMultipleInstances = true)]
private bumper.ContactSensorArrayOperations _mainPort = new
      bumper.ContactSensorArrayOperations();

[Partner("ARobot", Contract = arobot.Contract.Identifier,
CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate,
Optional = false)]
private arobot.ARobotOperations _aRobotPort = new
arobot.ARobotOperations();

[Partner(dssp.Partners.SubscriptionManagerString, Contract = submgr.Contract.Identifier,
CreationPolicy = PartnerCreationPolicy.CreateAlways,
Optional = false)]
private submgr.SubscriptionManagerPort _subMgrPort = new
      submgr.SubscriptionManagerPort();

In the code for the Start method, we will initialize the state for the contact sensor array and then use the subscribe operation to receive whisker notifications. The code for the Start method will look like the following:

protected override void Start()
{
    InitializeState();

    // Subscribe to the ARobot for whisker notifications
    SubscribeToARobot();

   base.Start();
}

The SubscribeToARobot method is responsible for creating a notification port and then sending a Subscribe request to the ARobot notification port. It uses the Arbiter.Receive method to indicate that the service should wait for a response, and, if the response is an error, then it logs that error. The code for the SubscribeToARobot method is as follows:

private IEnumerator<ITask> SubscribeToARobot()
{
     // Create a notification port
     arobot.ARobotOperations notificationPort = new
           arobot.ARobotOperations();

     Fault f = null;
     // Subscribe to the ARobot and wait for a response
     yield return Arbiter.Choice(_aRobotPort.Subscribe(notificationPort),
          delegate(SubscribeResponseType Rsp)
          {     },
          delegate(Fault fault)
          {
             LogError("Subscription failed", fault);
          }
     );

     base.MainPortInterleave.CombineWith(new Interleave(
        new ExclusiveReceiverGroup(
          Arbiter.Receive<arobot.UpdateWhiskers>(
            true, notificationPort, SensorsChangedHandler)
          ), new ConcurrentReceiverGroup()
     ));
 }

The SubscribeToARobot method registers a message handler when it subscribes to the ARobot. This message handler, named SensorChangedHandler, is responsible for determining which sensor has been activated and then updating the generic contact sensor property named Pressed. This property indicates whether one of the contact sensors has been pressed. It also sends a notification to the subscription manager port, which indicates that all subscribers should be notified of the update. The code for the SensorsChangedHandler is as follows:

private void SensorsChangedHandler(arobot.UpdateWhiskers notification)
{
     bool changed = false;
     bumper.ContactSensor bumper = null;

     for (int i = 0; i < _state.Sensors.Count; i++)
     {
        bumper = _state.Sensors[i];

        if (bumper.HardwareIdentifier == 1 &&
              bumper.Pressed != notification.Body.WhiskerLeft)
        {
            bumper.Pressed = (notification.Body.WhiskerLeft);
            changed = true;
            break;
        }

        if (bumper.HardwareIdentifier == 2 &&
              bumper.Pressed != notification.Body.WhiskerRight)
        {
            bumper.Pressed = (notification.Body.WhiskerRight);
            changed = true;
            break;
        }

     }

     if (changed)
     {
        this.SendNotification<bumper.Update>(_subMgrPort, new
             bumper.Update(bumper));
     }

    }

After all the changes are made to the ARobotBumper service and you have added class files representing the LED and speaker services, you can compile the ARobotServices project and create the assembly files in the bin folder for the MSRS installation. The next step is to create a test service that can use these new services to control the ARobot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.49.243