}
假如你在用藍牙,你可能需要添加一個header,它包括的消息(message)的長度。當(dāng)從COM口接收到數(shù)據(jù)后,你應(yīng)該向服務(wù)的內(nèi)部端口(internal port)提交數(shù)據(jù),如果想更新服務(wù)的狀態(tài),你要確保消息的處理方法是獨占使用這個服務(wù)的狀態(tài)的,也就是要獲得服務(wù)狀態(tài)的鎖,這樣才可以改變服務(wù)的狀態(tài)。
關(guān)于 內(nèi)部端口(internal port)、服務(wù)(Service)、消息(Message)等名詞的定義請查看相關(guān)資料 。
1 void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
2 {
3 //
4 //Do not modify your state yet
5 _myRobotInboundPort.Post(sensorMsg);
6 }
7 //
8 protected override void Start()
9 {
10 Interleave mainInterleave = ActivateDsspOperationHandlers();
11 mainInterleave.CombineWith(new Interleave(
12 new TeardownReceiverGroup(),
13 new ExclusiveReceiverGroup(
14 Arbiter.ReceiveWithIterator(true, _myRobotInboundPort, MyRobotSensorMessageHandler)
15 ),
16 new ConcurrentReceiverGroup()
17 ));
18 }
19 private IEnumerator MyRobotSensorMessageHandler(SensorNotification sensorMessage)
20 {
21 //update state here
22 _state.sensor = sensorMessage.sensor;
23 //
24 }
25 //
26
第三步:使用Brick Service
Brick Service 負責(zé)處理對機器人的訪問,它把執(zhí)行請求發(fā)送給機器人并且將機器人的傳感器信息發(fā)送回訂閱Brick Service的服務(wù)。
在前面的兩個實例Service Tutorial 4 (C#) - Supporting Subscriptions和 Service Tutorial 5 (C#) – Subscribing中我們了解了服務(wù)的訂閱(subscription)方法,但是這兩個例子中描述的服務(wù)訂閱和這里的并不完全合適,前面實例中的服務(wù)訂閱會將所有傳感器數(shù)據(jù)返回給訂閱者,而下面所說的自定義服務(wù)(Custom Subscriptions)只返回傳感器數(shù)據(jù)的一個子集,例如一個訂閱了brickService的紅外傳感器服務(wù)并不想獲取其他傳感器的數(shù)據(jù),它只是獲得紅外傳感器的數(shù)據(jù),如一個接觸(Contract)傳感器服務(wù)只訂閱了碰撞傳感器(bumper)的數(shù)據(jù),它也不會得到其他傳感器的數(shù)據(jù),下面就講解如何是自定義訂閱服務(wù)。
自定義訂閱(Custom Subscriptions)
和一般訂閱的實現(xiàn)方式一樣,自定義訂閱同樣使用訂閱管理器(subscription manager)處理消息的通知,不同的是,當(dāng)一個自定義訂閱請求發(fā)送到被訂閱服務(wù),同時也會附帶發(fā)送一個消息,這個消息用來告訴被訂閱服務(wù)我們要訂閱那些傳感器的數(shù)據(jù),這個消息是一個列表(List),是一個要訂閱的傳感器的名稱的列表,被訂閱服務(wù)可以支持這個傳感器名稱列表的“邏輯或”或者“邏輯與” 操作(邏輯或即如何列表里有任一個數(shù)據(jù)改變,就要發(fā)出通知,邏輯與即列表里所有傳感器數(shù)據(jù)發(fā)生改變才發(fā)出通知。)
下面的代碼演示了使用一個邏輯或來訂閱服務(wù),也就是說當(dāng)任何一個過濾字符串匹配后,它都會通知訂閱者,假如邏輯與被實現(xiàn),需要所有的過濾字符串匹配后才會通知訂閱者。
首先,添加自定閱操作到類型文件(type file):
1 public class MyBrickServiceOperations : PortSet
2 <
3 DsspDefaultLookup,
4 DsspDefaultDrop,
5 Get,
6 //IMPORTANT: Because SelectiveSubscribe inherits from Subscribe, it must go>
圖4-添加服務(wù)代理的引用
為brick service proxy添加命名空間
1 using brick = Robotics.MyBrickService.Proxy;
添加brick service為伙伴服務(wù)
1 [Partner("MyBrickService",
2 Contract = brick.Contract.Identifier,
3 CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate,
4 Optional = false)]
5 brick.MyBrickServiceOperations _myBrickPort = new brick.MyBrickServiceOperations();
6
實現(xiàn) SetMotorPower消息
1 [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
2 public IEnumerator SetMotorPowerHandler(motor.SetMotorPower setMotorPower)
3 {
4 //flip direction if necessary
5 double revPow = setMotorPower.Body.TargetPower;
6 if (_state.ReversePolarity)
7 {
8 revPow *= -1.0;
9 }
10
11 //update state
12 _state.CurrentPower = revPow;
13
14 //convert to native units
15 int power = (int)Math.Round(revPow * _state.PowerScalingFactor);
16
17 //send hardware specific motor data
18 brick.SetMotor motordata = http://www.robotain.com/tech/articles/201001/new brick.SetMotor();