Serialization Problems
I have a some services which, when running on the same node, work fine. When I switch to running over tcp/ip, I get the following errors:
### SerializerForwarder:ReportFailure. Exception:There is an error in XML document (1, 1). Action: Body Type:null Target Service: Source Service:
And
### Transportssp.tcp://dgfslqc1:40001/:Aborting outbound request, data packet not found
I have some general questions. Originally I was trying to send an ArrayList, but it was failing with the error above. I assumed it was a problem with the ArrayList so I created a work around and I'm still getting this error. One of my objects is nothing but a bunch of doubles, yet it still does not get through. Other which are doubles/strings/bools DO get sent through.
In addition to my problem above, is there any way to know which objects are serializable and which are not?
Thanks,
Don
[1406 byte] By [
Don] at [2008-3-7]
Hello Don. There are currently many data types which are not Xml Serializable. We are working on solutions to these issues in the final release of MSRS 1.5.
ArrayList is not supported because it is not strongly typed. In the next release, you should be able to use many more complex data types, such as List of List, Dictionary, Uri, etc.
If you post with the specific data members you are interested in, I will make sure we address these scenarios, or at least have a similar solution which works.
quite a few of our service contracts include a TimeStamp field, which is of DateTime, and it serializes fine (for example running simpledashboard, one one node, and then starting another node that starts simulationtutorial2, will demonstrate this, since it sends timestamped laser data)
Can you include your type definition?
As david mentioned we are beefing up our serialization support, working around CLR XmlSerializer limitations, and also having a better way detecting if something will serialize
Maybe serialization isn't even my problem.
Let me give a more detailed explanation of my situation and then maybe someone will have an idea.
I have a bunch of serivces, which run on a PC located on the robot. Pretty much all of the intelligence is contained in these services and the entire architecture runs on a single node (primarily because we do not have room for a second processor on the robot).
With that system in place and functioning properly, I want to run a GUI serivce on an external computer that is networked to the computer on the robot. The gui is a MSRS service with a win forms app that basically gives visual feedback for all of the sensors in real time along with other useful information such as the current state of all running services, etc.
I first start up all of the robot services, and then I manually start the GUI. If I run the GUI on the same node, everything partners correctly, all messages get sent/received, and all is well. The GUI takes up significant resources, and the system can get sluggish, especially when the robot is doing vision processing. Thus, the GUI needs to be move it to an external computer running over the network. This is where problems start. I thought I had the correct partnership technique, but when I attempt to run the GUI over the network, about half of the messages get through. There doesn't seem to be any rhyme or reason to which messages are rejected (examples are presented below), and the error messages provide absolutely no hint as to what is wrong.
First, here is an example of how I perform my partner declarations from the GUI to services running on the robot. I made it static because I am under the assumption that those services are already running and thus they do not need to be created. Perhaps a suggestion could be made from someone at Microsoft.
For the sake of this example, I will assume that the GUI is called ControlCenter (which is what I call it), and the services running on the robot are service1, service2, etc..
Code Snippet
public
class SubD_ControlCenterService : DsspServiceBase {
[
Partner("CC_Service1", Contract = serv1.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)] serv1.
Service1Operations _serv1Port = new serv1.Service1Operations(); serv1.Service1Operations
_serv1Notify = new serv1.Service1Operations(); ....
Then in my OnStartup routine:
_CCShutdown =
new Port<Shutdown>(); serv1.
Subscribe serv1_subscribe = new serv1.Subscribe(new SubscribeRequestType()); serv1_subscribe.NotificationPort = _serv1Notify;
serv1_subscribe.NotificationShutdownPort = _CCShutdown;
_serv1Port.Post(serv1_subscribe);
yield return Arbiter.Choice(
serv1_subscribe.ResponsePort,
delegate(SubscribeResponseType response)
{
LogInfo("ControlCenter subscribed to Service1 Service");
},
delegate(Fault fault)
{
LogError(null, "ControlCenter Unable to subscribe to Service1 Service", fault);
}
);
...
I use that same code for each service that the GUI partners with.
Here is the manifest I use:
<?
<?xml version="1.0" ?> <
Manifest xmlns="http://schemas.microsoft.com/xw/2004/10/manifest.html" xmlns:d="http://schemas.microsoft.com/xw/2004/10/dssp.html" xmlns:f="http://schemas.tempuri.org/2007/03/controlcenter.html" >
<
CreateServiceList> <
ServiceRecordType> <
d:Contract>http://schemas.tempuri.org/2007/03/controlcenter.html</< FONT>d:Contract> <
d:PartnerList> <
d:Partner> <
d:Name>f:CC_Service1</< FONT>d:Name> <
d:ServiceDirectory>http://robotIPaddress:50000/directory</< FONT>d:ServiceDirectory> </< FONT></d:Partner>
... more partner definitions, same as above
</< FONT></d:PartnerList> </< FONT></ServiceRecordType>
</< FONT></CreateServiceList>
</< FONT></Manifest>
In the debug and trace messages menu for the external node, I do see the messages that "Control Center subscribe to service" for every single service. So that leads me to believe that a connect is being made and the services are partnering correctly.
With that said, immediately after the partnerships are made on the external node (where the GUI is running), I see a rush of "warning" messages that looks like this:
Code Snippet
| * | ### SerializerForwarder:ReportFailure. Exception:There is an error in XML document (0, 0). Action: Body Type:null Target Service: Source Service: |
| * | ### Transport:dssp.tcp://externalHostName:40001/:Aborting outbound request, data packet not found |
| * | ### SerializerForwarder:ReportFailure. Exception:There is an error in XML document (1, 1). Action: Body Type:null Target Service: Source Service: |
| * | ### SerializerForwarder:ReportFailure. Exception:Exception of type 'System.OutOfMemoryException' was thrown. Action: Body Type:null Target Service: Source Service: |
There doesn't seem to be any pattern to these messages, sometimes the same message is lumped together, sometimes all four appear together. They occur very frequently. In one of the seconds, based on timestamp, there were over 75 of those errors above, just repeated over and over. The errors give no indication as to what's wrong, where the problem is coming from, what messages are to blame, what services are the messages originating at, or where the messages are going. I cannot tell if it's an error for incoming messages, outgoing messages, or both.
SOME messages get through in both directions, as this is the most confusing part.
Here are some examples of messages that work:
Code Snippet
public class DistSpeedSettings : Update<DistanceSpeedSettings, PortSet<DefaultUpdateResponseType, Fault>>
{
}
[
DataContract] public class DistanceSpeedSettings {
[
DataMember] public double innerRadius; [
DataMember] public double innerRadiusSpeed; [
DataMember] public double innerDistance1; [
DataMember] public double innerDistance1Speed; [
DataMember] public double innerDistance2; [
DataMember] public double innerDistance2Speed; [
DataMember] public double distance1; [
DataMember] public double distance1Speed; [
DataMember] public double distance2; [
DataMember] public double distance2Speed; [
DataMember] public double distance3; [
DataMember] public double distance3Speed; [
DataMember] public double distance4; [
DataMember] public double distance4Speed; }
[
DataContract] public class WayPoint {
[
DataMember] public double X; [
DataMember] public double Y; [
DataMember] public double Heading_SP; [
DataMember] public double Depth_SP; [
DataMember] public double maxFrequency; [
DataMember] public bool active; }
public class SetWayPoint : Update<WayPoint, PortSet<DefaultUpdateResponseType, Fault>> {
}
Here are some messages that are not getting through (this is the majority)
Code Snippet
[
DataContract()] public class DVLPacket {
// Most Common variables first [
DataMember] public DateTime timeStamp; [
DataMember] public bool checksumError; [
DataMember] public uint ensembleNumber; [
DataMember] public double depth; [
DataMember] public double depth_unfiltered; [
DataMember] public double heading; [
DataMember] public double pitch; [
DataMember] public double roll; [
DataMember] public double temperature; [
DataMember] public double pressure; [
DataMember] public ushort speedOfSound; [
DataMember] public double speed; // in direction of heading [
DataMember] public double speedS; // in direction perpendicular to heading [
DataMember] public double axisVelocity1; // Starboard [
DataMember] public double axisVelocity2; // Forward [
DataMember] public double axisVelocity3; // Vertical [
DataMember] public double axisVelocity4; // Error [
DataMember] public double axisDMG1; // Starboard [
DataMember] public double axisDMG2; // Forward [
DataMember] public double axisDMG3; // Vertical [
DataMember] public double axisDMG4; // Error [
DataMember] public byte sensorsAvailable; [
DataMember] public ushort salinity; [
DataMember] public byte headingStdDev; [
DataMember] public byte pitchStdDev; [
DataMember] public byte rollStdDev; [
DataMember] public uint pressureVariance; [
DataMember] public ushort pingsPerEnsemble; [
DataMember] public byte minVelocityCorrelation; [
DataMember] public byte minBottomCorrelation; [
DataMember] public ushort errorVelocityMaximum; [
DataMember] public int pressureRaw; [
DataMember] public int temperatureRaw; [
DataMember] public double beamRangeBR; [
DataMember] public double beamRangeBL; [
DataMember] public double beamRangeFR; [
DataMember] public double beamRangeFL; [
DataMember] public byte beamCorrelationBR; [
DataMember] public byte beamCorrelationBL; [
DataMember] public byte beamCorrelationFR; [
DataMember] public byte beamCorrelationFL; [
DataMember] public byte beamStrengthBR; [
DataMember] public byte beamStrengthBL; [
DataMember] public byte beamStrengthFR; [
DataMember] public byte beamStrengthFL; [
DataMember] public byte beamPercentGoodBR; [
DataMember] public byte beamPercentGoodBL; [
DataMember] public byte beamPercentGoodFR; [
DataMember] public byte beamPercentGoodFL; [
DataMember] public ushort trackingDepthMax_SP; [
DataMember] public byte reduceReceiverGain_SP; }
public class DVLUpdate : Update<DVLPacket, PortSet<DefaultUpdateResponseType, Fault>> {
}
[
DataContract()] public class GridElement {
// Most Common variables first [
DataMember] public DateTime TimeStamp; [
DataMember] public uint EnsembleNumber; [
DataMember] public double Depth; //decimeters [
DataMember] public double Heading; // .01 degrees [
DataMember] public double Pitch; // .01 degrees [
DataMember] public double Roll; // .01 degrees [
DataMember] public double Temperature; // .01 F [
DataMember] public double Pressure; // in Psi [
DataMember] public double Speed; // in decimeters/s [
DataMember] public double SpeedS; // in decimeters/s [
DataMember] public double CurEarthVelX; // East Vel in decimeters/s [
DataMember] public double CurEarthVelY; // North Vel in decimeters/s [
DataMember] public double CurEarthVelZ; // Vertical Vel in decimeters/s [
DataMember] public double CurEarthVelErr; // Error [
DataMember] public double CurEarthPosX; // East Pos in decimeters [
DataMember] public double CurEarthPosY; // North in decimeters [
DataMember] public double CurEarthPosZ; // Depth? in decimeters [
DataMember] public double CurEarthPosErr; // Error [
DataMember] public int EarthVelX; // East Vel in decimeters/s [
DataMember] public int EarthVelY; // North Vel in decimeters/s [
DataMember] public int EarthVelZ; // Vertical Vel in decimeters/s [
DataMember] public int EarthVelErr; // Error [
DataMember] public int EarthPosX; // East Pos in decimeters [
DataMember] public int EarthPosY; // North in decimeters [
DataMember] public int EarthPosZ; // Depth? in decimeters [
DataMember] public int EarthPosErr; // Error [
DataMember] public int Pipe; // [
DataMember] public int HydroPhoneDir; // Average hydrophone direction? }
public class AddGridElement : Update<GridElement, PortSet<DefaultUpdateResponseType, Fault>> {
}
From a serialization point of view, I don't see any reason why these objects should cause an "XML error (0,0)".
I have found instances where a saved state xml file will have an extra ">" at the end of the XML document, causing it to fail when I try to create the state from that file, something like
"</Service1State>>" This is a big problem in itself, but maybe it's the topic of a different thread. I don't see how this could be a reason to have an error at (0,0) in the XML document, which is being created on the fly, unless it's the result of a flaw in MSRS.
This is the best explanation of my problem that I believe I can give, unless someone has a specific question. This has become a show stopping issue because the GUI is vital for testing of the robot, and at the same time, vision processing is vital as well. The two cannot run on at the same time on the same CPU, and we're currently running the fastest available low power Core 2 Duo with 2GB of RAM. It is also very inconvenient to have to run the GUI on the robot via remote desktop, because it's slow and laggy.
Any advice/suggestions/help would be greatly appreciated!!
-Don
Don at 2007-9-26 >
