Adding a second light sensor on the NXT
Hi,
I've successfully got one light sensor configured on my NXT, however whenever I try to add a a second light sensor, only the one light sensor recieves results, albeit through now two handlers. I assume the problem is that I'm subscribing "both" of my light sensors through the same port, but I am unsure how to subscribe the second one on a different port.
My LightSensor1 config.xml file has it pointing to "hardwareidentifier" 1
and my LightSensor2 config.xml has it pointing to "hardwareidentifier" 2
Below is my code:
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml;
using moth = Robotics.Moth;
using analog = Microsoft.Robotics.Services.AnalogSensor.Proxy;
using lightSensor = Microsoft.Robotics.Services.LegoNxt.LightSensor.Proxy;
namespace Robotics.Moth
{
///<summary>
/// The LightTest Service
///</summary>[
DisplayName("LightTest"
)][
Description("The LightTest Service"
)][Contract(
Contract.Identifier)]publicclass
LightTestService :DsspServiceBase{
///<summary>/// _state
///</summary>private
LightTestState _state =new
LightTestState();///<summary>/// _main Port
///</summary>[
ServicePort("/lighttest"
, AllowMultipleInstances=true
)]private
LightTestOperations _mainPort =new
LightTestOperations();///<summary>/// Default Service Constructor
///</summary>///[
Partner(lightSensor.Contract.Identifier +"LightSensor1"
, Contract = lightSensor.Contract.Identifier, Optional =false
, CreationPolicy =PartnerCreationPolicy.UseExisting)]private
analog.AnalogSensorOperations _analog =new
analog.AnalogSensorOperations();[
Partner(lightSensor.Contract.Identifier +"LightSensor2"
, Contract = lightSensor.Contract.Identifier, Optional =false
, CreationPolicy =PartnerCreationPolicy.UseExisting)]private
analog.AnalogSensorOperations _analog2 =new
analog.AnalogSensorOperations();public
LightTestService(DsspServiceCreationPort creationPort) :base
(creationPort){
}
///<summary>/// Service Start
///</summary>protectedoverridevoid
Start(){
// Listen on the main port for requests and call the appropriate handler.
ActivateDsspOperationHandlers();
// Publish the service to the local service Directory
DirectoryInsert();
// Start listening for sensors
SubscribeToSensors();
// Display HTTP service URI.
LogInfo(
LogGroups.Console,"Service uri: "
);}
void
SubscribeToSensors(){
// Create the sensor notification port.
analog.
AnalogSensorOperations analogNotificationPort =new
analog.AnalogSensorOperations();analog.
AnalogSensorOperations analogNotificationPort2 =new
analog.AnalogSensorOperations();_analog.Subscribe(analogNotificationPort);
_analog2.Subscribe(analogNotificationPort2);
// Start listening for updates from the analog service.
Activate(
Arbiter.Receive<analog.Replace>(true
, analogNotificationPort, AnalogHandler));Activate(
Arbiter.Receive<analog.Replace>(true
, analogNotificationPort2, AnalogHandler2));}
privatevoid
AnalogHandler(analog.Replace notification){
LogInfo(
LogGroups.Console,"from: 1: "
+ notification.Body.NormalizedMeasurement.ToString());}
privatevoid
AnalogHandler2(analog.Replace notification){
LogInfo(
LogGroups.Console,"from 2: "
+ notification.Body.NormalizedMeasurement.ToString());}
///<summary>/// Get Handler
///</summary>///<param name="get"></param>///<returns></returns>[
ServiceHandler(ServiceHandlerBehavior.Concurrent)]publicvirtual
IEnumerator<ITask> GetHandler(Get get){
get.ResponsePort.Post(_state);
yieldbreak
;}
}
}
Just in case it's something wrong with my manifest or config files here they are:
Manifest:
<?xml version="1.0" ?>
<Manifest
xmlns="http://schemas.microsoft.com/xw/2004/10/manifest.html"
xmlns
ssp="http://schemas.microsoft.com/xw/2004/10/dssp.html"
xmlns:lego="http://schemas.microsoft.com/robotics/2006/05/legonxt.html"
xmlns:analog="http://schemas.microsoft.com/2006/06/analogsensor.html"
>
<CreateServiceList>
<ServiceRecordType>
<dssp:Contract>http://schemas.tempuri.org/2007/06/lighttest.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp:Name>analog:LightSensor1</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>analog:LightSensor2</dssp:Name>
</dssp
artner>
</dssp
artnerList>
</ServiceRecordType>
<!--Start LegoNXT Brick -->
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/robotics/2006/05/legonxt.html</dssp:Contract>
<dssp
artnerList>
<!--Initial LegoNXT config file -->
<dssp
artner>
<dssp
ervice>LEGO.NXT.Brick.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>lego:Brick1</Name>
</ServiceRecordType>
<!-- Start Lego Light Sensor-->
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor1.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>analog:LightSensor1</Name>
</ServiceRecordType>
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor2.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>analog:LightSensor2</Name>
</ServiceRecordType>
</CreateServiceList>
</Manifest>
LightSensor1.Config.xml
<?xml version="1.0" encoding="utf-8"?>
<AnalogSensorState
xmlns
="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns
="http://schemas.microsoft.com/xw/2004/10/dssp.html"
xmlns="http://schemas.microsoft.com/robotics/2006/06/lightsensor.html">
<TimeStamp>0001-01-01T00:00:00</TimeStamp>
<HardwareIdentifier>2</HardwareIdentifier>
<RawMeasurement>0</RawMeasurement>
<NormalizedMeasurement>0</NormalizedMeasurement>
<RawMeasurementRange>100</RawMeasurementRange>
<Pose>
<Position xmlns="http://schemas.microsoft.com/robotics/2006/07/physicalmodel.html">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Position>
<Orientation xmlns="http://schemas.microsoft.com/robotics/2006/07/physicalmodel.html">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<W>0</W>
</Orientation>
</Pose>
</AnalogSensorState>
LightSensor2.Config.xml
<?xml version="1.0" encoding="utf-8"?>
<AnalogSensorState
xmlns
="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns
="http://schemas.microsoft.com/xw/2004/10/dssp.html"
xmlns="http://schemas.microsoft.com/robotics/2006/06/lightsensor.html">
<TimeStamp>0001-01-01T00:00:00</TimeStamp>
<HardwareIdentifier>1</HardwareIdentifier>
<RawMeasurement>0</RawMeasurement>
<NormalizedMeasurement>0</NormalizedMeasurement>
<RawMeasurementRange>100</RawMeasurementRange>
<Pose>
<Position xmlns="http://schemas.microsoft.com/robotics/2006/07/physicalmodel.html">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Position>
<Orientation xmlns="http://schemas.microsoft.com/robotics/2006/07/physicalmodel.html">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<W>0</W>
</Orientation>
</Pose>
</AnalogSensorState>
If no one can see how to fix my code, how about just an example of how to recieve from two sensors (of any type) on the NXT...
Hi, your code looks fine. In the NXT brick service web page, did you configure the NXT sensors (both ports) to be of type Light?
any errors in the console?
Hi i noticed an error in the manifest (good thing we will be providing a graphical manifest editor, manifests are hard to work with). You partner names are wrong. They need to match exactly, the full qualified name, if what your service defines:
<dsspartnerList>
<dsspartner>
<dssp:Name>analog:LightSensor1</dssp:Name>
</dsspartner>
<dsspartner>
<dssp:Name>analog:LightSensor2</dssp:Name>
</dsspartner>
</dsspartnerList>
</ServiceRecordType>
above, instead of the analog qualifed namespace, use the same namespace as you used in your service partner attributes
Currently I have changed the manifests as suggested. However, every time I run the program I still just get the one light sensor registering values (but triggering both handlers). I have verified that both light sensors are working. Both are also being turned on when the program starts (I have them set to LightOn, so the red light comes on on both).
Everything seems good in my brick manifest file.
Here is my brick manifest:
Brick:
<?xml version="1.0" encoding="utf-8"?>
<LegoNxtState xmlns
="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns
="http://schemas.microsoft.com/xw/2004/10/dssp.html" xmlns="http://schemas.microsoft.com/robotics/2006/05/legonxt.html">
<ComPort>4</ComPort>
<BaudRate>115200</BaudRate>
<Connected>NotConnected</Connected>
<SensorPort>
<int>0</int>
<int>0</int>
<int>0</int>
<int>0</int>
</SensorPort>
<MotorSensorPort>
<int>0</int>
<int>0</int>
<int>0</int>
</MotorSensorPort>
<ButtonSensorPort>
<int>0</int>
<int>0</int>
<int>0</int>
</ButtonSensorPort>
<MotorOutputPort>
<int>0</int>
<int>0</int>
<int>0</int>
</MotorOutputPort>
<BatteryVoltage>0</BatteryVoltage>
<BrickConfig>
<SensorPort>
<SensorConfig>
<Type>LightOn</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
</SensorConfig>
<SensorConfig>
<Type>LightOn</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
</SensorConfig>
<SensorConfig>
<Type>Null</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
</SensorConfig>
<SensorConfig>
<Type>Sonar</Type>
<LowThresh>0</LowThresh>
<HighThresh>250</HighThresh>
<ExternalRange>false</ExternalRange>
</SensorConfig>
</SensorPort>
<MotorPort>
<MotorConfig>
<Type>Encoder</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
<TicksPerRevolution>6</TicksPerRevolution>
</MotorConfig>
<MotorConfig>
<Type>Null</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
<TicksPerRevolution>6</TicksPerRevolution>
</MotorConfig>
<MotorConfig>
<Type>Encoder</Type>
<LowThresh>0</LowThresh>
<HighThresh>0</HighThresh>
<ExternalRange>false</ExternalRange>
<TicksPerRevolution>6</TicksPerRevolution>
</MotorConfig>
</MotorPort>
<ButtonPort>
<string>Null</string>
<string>Null</string>
<string>Button</string>
</ButtonPort>
<AvailableSensorTypes>
<string>Null</string>
<string>Touch</string>
<string>LightOn</string>
<string>LightOff</string>
<string>Sound</string>
<string>Sonar</string>
</AvailableSensorTypes>
<AvailableMotorSensorTypes>
<string>Null</string>
<string>Angle</string>
<string>Encoder</string>
</AvailableMotorSensorTypes>
<AvailableButtonSensorTypes>
<string>Null</string>
<string>Button</string>
</AvailableButtonSensorTypes>
</BrickConfig>
</LegoNxtState>
Also something I just noticed, depending on which one these is listed first, that determines which sensor is the one that I end up getting values from in the handlers. It is always the first one listed that is the one that ends up working.
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor2.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>lightsensor:LightSensor2</Name>
</ServiceRecordType>
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor1.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>lightsensor:LightSensor1</Name>
</ServiceRecordType>
this might a lego NXT brick service issue. We willlook into it. The code is available, if you have the time, you can investigate the notifications being sent from the lego NXT service, and see if they are tagged properly.
Also, to avoid the multitude of happy and silly face icons, mark your XML with the code icon, in the editor.
thanx
g
so my code looks correct then?
Is there a way around this issue, like another way I might register the sensors or something that might get around the bug?
I switched to using 1.5 instead of 1.0, just to see if that was the issue, but no dice, still the same results of only being able to read from one light sensor.
On the debug panel this is what I get concerning the light sensor subscription
Adding subscriptions for: LIGHTON2
Category StdOut
Level Info
Time 2007-06-14T05:08:45.77-07:00
Subject Adding subscription for: LIGHTON2
Source http://apollo:50000/legonxt/b8624d5b-0c4a-44a7-b879-7f2d3b6b0bf8
CodeSite Boolean MoveNext()() at line:0, file
Adding subscriptions for: LIGHTON1
Category StdOut
Level Info
Time 2007-06-14T05:08:45.77-07:00
Subject Adding subscription for: LIGHTON2
Source http://apollo:50000/legonxt/b8624d5b-0c4a-44a7-b879-7f2d3b6b0bf8
CodeSite Boolean MoveNext()() at line:0, file
It appears its registering two light sensors, although the source is the same for both. I don't know if that is the way it is supposed to be. As I said before both handlers are being triggered, even though only by the one light sensor or the other.
Although, now in 1.5 for no apparent reason it's always LightSensor1.Config.xml that determines which hardware port it reads from, which is different from what was happening in my 1.0 version, where the sensor that was chosen depended on which was listed first in the main manifest file on this part:
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor1.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>lightsensor:LightSensor1</Name>
</ServiceRecordType>
<ServiceRecordType>
<dssp:Contract>http://schemas.microsoft.com/2006/06/legonxtlightsensor.html</dssp:Contract>
<dssp
artnerList>
<dssp
artner>
<dssp
ervice>LightSensor2.Config.xml</dssp
ervice>
<dssp:Name>dssp
tateService</dssp:Name>
</dssp
artner>
<dssp
artner>
<dssp:Name>lego:Brick1</dssp:Name>
</dssp
artner>
</dssp
artnerList>
<Name>lightsensor:LightSensor2</Name>
</ServiceRecordType>
Oh and I am hitting the "this post contains a code sample", but I still get the smiley faces... perhaps my computer is possessed...