19 motordata.PowerSetpoint = power;
20
21 yield return Arbiter.Choice(
22 _myBrickPort.SendMotorCommand(motordata),
23 delegate(DefaultUpdateResponseType success)
24 {
25 setMotorPower.ResponsePort.Post(success);
26 },
27 delegate(Fault failure)
28 {
29 setMotorPower.ResponsePort.Post(failure);
30 }
31 );
32
33 yield break;
34 }
35
訂閱服務
我們創(chuàng)建的大多數(shù)的服務是為了獲取傳感器的數(shù)據(jù)為目的的,這就需要這些服務去訂閱Birck Service,他們使用上面所實現(xiàn)的自定義訂閱來訂閱相應的傳感器數(shù)據(jù),下面我們看一個MyRobotBumper服務,這個服務實現(xiàn)了 Robotics Common中的ContactSensorArray服務的Contract,和上面所說Motor Service的創(chuàng)建方式類似。
1 using bumper = Microsoft.Robotics.Services.ContactSensor.Proxy;
2 using brick = Robotics.MyBrickService.Proxy;
3 using submgr = Microsoft.Dss.Services.SubscriptionManager;
4
5 private void SubscribeToNXT()
6 {
7 // Create a notification port
8 brick..MyBrickServiceOperations _notificationPort = new brick.MyBrickServiceOperations();
9 //create a custom subscription request
10 brick.MySubscribeRequestType request = new brick.MySubscribeRequestType();
11 //select only the sensor and ports we want
12 //NOTE: this name must match the names you define in MyBrickService
13 request.Sensors = new List();
14 foreach (bumper.ContactSensor sensor in _state.Sensors)
15 {
16 //Use Identifier as the port number of the sensor
17 request.Sensors.Add("TOUCH" + sensor.Identifier);
18 }
19 //Subscribe to the brick and wait for a response
20 Activate(
21 Arbiter.Choice(_myBrickPort.SelectiveSubscribe(request, _notificationPort),
22 delegate(SubscribeResponseType Rsp)
23 {
24 //update our state with subscription status
25 subscribed = true;
26 LogInfo("MyRobotBumper subscription success");
27 //Subscription was successful, start listening for sensor change notifications
28 Activate(
29 Arbiter.Receive
30 (true, _notificationPort, SensorNotificationHandler)
31 );
32 },
33 delegate(Fault F)
34 {
35 LogError("MyRobotBumper subscription failed");
36 })
37 );
38 }
39 private void SensorNotificationHandler(brick.Replace notify)
40 {
41 //update state
42 foreach (bumper.ContactSensor sensor in _state.Sensors)
43 {
44 bool newval = notify.Body.SensorPort[sensor.Identifier - 1] == 1 ? true : false;
45 bool changed = (sensor.pssed != newval);
46 sensor.TimeStamp = DateTime.Now;
47 sensor.pssed = newval;
48 if (changed)
49 {
50 //notify subscribers on any bumper pssed or unpssed
51 _subMgrPort.Post(new submgr.Submit(sensor, DsspActions.UpdateRequest));
52 }
53 }
54 }
55
擴展狀態(tài)
前面的模式很容易實現(xiàn)并且在大多數(shù)情況下可以正常工作,因為狀態(tài)和操作是通用的,但是,有時候我們還是想為狀態(tài)添加一些信息或者添加一些操作類型,一個好的例子就是 sonar as bumper 服務,這個服務使用聲波傳感器代替一個碰撞傳感器,這個服務實現(xiàn)了ContactSensorArray服務的Contract,除非你自己想添加自己狀態(tài),你需要這樣的做的原因是這個服務需要包括一個距離和閾值的數(shù)據(jù)信息,這些在Contract服務沒有給出。
注意你的狀態(tài)類是繼承自ContactSensorArrayState 。
調(diào)整實現(xiàn)文件:
1
2 using bumper = Microsoft.Robotics.Services.ContactSensor.Proxy;
3 using brick = Robotics.MyBrickService.Proxy;
4 using submgr = Microsoft.Dss.Services.SubscriptionManager;
5 namespace Robotics.MyRobotSonarAsBumper
6 {
7 [Contract(Contract.Identifier)]
8 [AlternateContract(bumper.Contract.Identifier)]
9 [PermissionSet(SecurityAction.PermitOnly, Name="Execution")]
10 public class MyRobotSonarAsBumperService : DsspServiceBase
11 {
12 [InitialStatePartner(Optional = true)]
13 private MyRobotSonarAsBumperState _state;
14 [ServicePort("/MyRobotSonarAsBumper", AllowMultipleInstances = true)]
15 private MyRobotSonarAsBumperOperations _mainPort = new MyRobotSonarAsBumperOperations();
16 [AlternateServicePort(
17 "/MyRobotBumper",
18 AllowMultipleInstances = true,
19 AlternateContract=bumper.Contract.Identifier
20 )]
21 private bumper.ContactSensorArrayOperations
22 _bumperPort = new bumper.ContactSensorArrayOperations();
23 [Partner(
24 "MyRobotBrick",
25 Contract = brick.Contract.Identifier,