Go to Post I think the GDC should force us to use steam engines, but the electrically-inclined folks on my team might stop whining if they're given more to work with. - Madison [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 16-04-2010, 18:06
byteit101's Avatar
byteit101 byteit101 is offline
WPILib maintainer (WPI)
AKA: Patrick Plenefisch
no team (The Cat Attack (Formerly))
Team Role: Programmer
 
Join Date: Jan 2009
Rookie Year: 2009
Location: Worcester
Posts: 699
byteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of light
Dashboard Packet (Robot to Dashboard)

Does anyone know what the bits in the status and error bytes represent?
I have a document that claims what some of the status bits are, but the LV dashboard contradicts this.

Also, assuming buffer is a byte array of the packet, would this be the correct interpretation of the packet:
(C#)
Code:
PacketNumber = buffer[0]+(buffer[1] >> 8);
DigitalIn = new DIOBitField(buffer[2]);
DigitalOut = new DIOBitField(buffer[3]);
Battery = float.Parse(buffer[4].ToString("x")+"." + buffer[5].ToString("x"));//to hex
Status = new StatusBitField(buffer[6]);
Error = new ErrorBitField(buffer[7]);
Team = (int)buffer[8] + (int)(buffer[9] >> 8);
How would one parse the version bytes? Are they ASCII?
__________________
Bubble Wrap: programmers rewards
Watchdog.Kill();
printf("Watchdog is Dead, Celebrate!");
How to make a self aware robot: while (∞) cout<<(sqrt(-∞)/-0);
Previously FRC 451 (The Cat Attack)
Now part of the class of 2016 at WPI & helping on WPILib

Last edited by byteit101 : 17-04-2010 at 16:39.
  #2   Spotlight this post!  
Unread 19-04-2010, 08:49
slavik262's Avatar
slavik262 slavik262 is offline
We do what we must because we can.
AKA: Matt Kline
FRC #0537 (Charger Robotics)
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Sussex, WI
Posts: 310
slavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to behold
Send a message via AIM to slavik262
Re: Status and Error Bytes from Dashboard Packet

I've always been going off the documentation of Eric Haskins, but I don't know what the LV dashboard lays out. Later today I'll check how my code interprets the packet (I wrote it a while back) and let you know if your code looks right. At first glance that looks fine, but I'll double check for you.

The version bytes are ASCII. Also, don't forget to calculate your crc32 checksum and make sure it matches with the checksum at the end of the packet before doing any other parsing - otherwise your code is just wasting time with bad data.
__________________
  #3   Spotlight this post!  
Unread 19-04-2010, 16:43
Radical Pi Radical Pi is offline
Putting the Jumper in the Bumper
AKA: Ian Thompson
FRC #0639 (Code Red Robotics)
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2010
Location: New York
Posts: 655
Radical Pi has a spectacular aura aboutRadical Pi has a spectacular aura aboutRadical Pi has a spectacular aura about
Re: Status and Error Bytes from Dashboard Packet

I believe the data in the bytes is the same as the indicators that are shown to the Scorekeeper by the FMS. Maybe I can dig up the manual
__________________

"To have no errors would be life without meaning. No strugle, no joy"
"A network is only as strong as it's weakest linksys"
  #4   Spotlight this post!  
Unread 20-04-2010, 00:26
EHaskins EHaskins is offline
Needs to change his user title.
AKA: Eric Haskins
no team (CARD #6 (SCOE))
Team Role: College Student
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Elkhorn, WI USA
Posts: 998
EHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond reputeEHaskins has a reputation beyond repute
Send a message via MSN to EHaskins
Re: Status and Error Bytes from Dashboard Packet

That looks like it should work.

Here is some more info/code if you can use it.

When processing dashboard data in .net Jon Skeet's EndianBinaryReader (http://www.yoda.arachsys.com/csharp/miscutil/) will be useful. It data fully supports both big and little endian.

A complete version of the code I show below is available at http://frc1103dashboard.codeplex.com...ses/view/41737.

The following code (VB 2008) is used to decode the non-user data. DsIinputs/Outputs simply break the bits into a boolean array, and RobotStatus/Error were never implemented.
Code:
    Public Function Parse(ByVal data As Byte()) As Byte()
        Dim reader As EndianBinaryReader = Nothing
        Try
            'reader = New BinaryReader(New MemoryStream(data))
            reader = New MiscUtil.IO.EndianBinaryReader(New MiscUtil.Conversion.BigEndianBitConverter(), New MemoryStream(data))

            dataGraph.PacketNumber = reader.ReadUInt16()
            dataGraph.DigitalIns = New DsInputs(reader.ReadByte())
            dataGraph.DigitalOuts = New DsOutputs(reader.ReadByte())
            dataGraph.Battery = reader.EReadBattery()

            dataGraph.Status = New RobotStatus(reader.ReadByte())
            dataGraph.Errors = New RobotError(reader.ReadByte())

            dataGraph.TeamNumber = reader.ReadTeamNumber()

            Dim versionBytes As Byte() = reader.ReadBytes(8)
            dataGraph.DSVersion = Text.Encoding.ASCII.GetString(versionBytes)

            dataGraph.UnusedBuffer1 = reader.ReadUInt32()
            dataGraph.UnusedBuffer2 = reader.ReadUInt16()

            'I believe this is only important for robot-to-DS communication, but haven't confirmed.
            dataGraph.ReplyPacketNumber = reader.ReadUInt16()

            Dim userData = reader.ReadBytes(984)
            dataGraph.UserData = userData
            Return userData
            reader.Close()

            Return data
        Catch ex As Exception
            'TODO: Add exception handling logic.
            Throw
        Finally
            If reader IsNot Nothing Then
                reader.Close()
            End If
        End Try
    End Function
(VB) The extension methods used above to decode battery, and team number.
Code:
Public Module BinaryReaderExtensions
    <Extension()> _
    Public Function ReadTeamNumber(ByVal reader As EndianBinaryReader) As Integer
        Dim temp1 = reader.ReadByte()
        Dim temp2 = reader.ReadByte()
        Return temp1 * 100 + temp2
    End Function

    <Extension()> _
    Public Function EReadBattery(ByVal reader As EndianBinaryReader) As Double
        ' battery voltage is transmitted follows: 0x12 0x17 is 12.17 volts.
        Return Convert.ToDouble(reader.ReadByte().ToString("x")) + (Convert.ToDouble(reader.ReadByte().ToString("x")) / 100.0)
    End Function
End Module
This code (C#) verifies the integrity of the packet, then forwards it, indirectly, to the above code.
Code:
        public void ParseBytes(byte[] data)
        {
            if (data.Length == DSPacketLength && FrcPacketUtils.VerifyFrcCrc(data))
            {
                UserData = data;
                SendNewData(data);
                InvalidPacketCount = 0;
            }
            else
            {
                InvalidPacketCount += 1;
                Debug.Print("Invalid DS data received, ignoring");
            }
        }
The VerifyFRCCrc function (VB)

Code:
    Public Function VerifyFrcCrc(ByVal data As Byte()) As Boolean
        Dim calculatedCrc As UInteger = 0
        Dim dataCrc As UInteger = 0
        Dim crc As New Crc32()

        dataCrc = BitConverter.ToUInt32(data.Skip(data.Length - 4).Take(4).ToArray(), 0)

        'remove CRC bytes from data before calculating CRC.
        Dim crcData(data.Length - 1) As Byte
        data.Take(data.Length - 4).ToArray.CopyTo(crcData, 0)

        calculatedCrc = BitConverter.ToUInt32(crc.ComputeHash(crcData), 0)

        Return dataCrc = calculatedCrc
    End Function
The CRC32 class I found on a blog somewhere, but don't have documentation of where.

Code:
using System;
using System.Security.Cryptography;

public class Crc32 : HashAlgorithm
{
    public const UInt32 DefaultPolynomial = 0xedb88320;
    public const UInt32 DefaultSeed = 0xffffffff;

    private UInt32 hash;
    private UInt32 seed;
    private UInt32[] table;
    private static UInt32[] defaultTable;

    public Crc32()
    {
        table = InitializeTable(DefaultPolynomial);
        seed = DefaultSeed;
        Initialize();
    }

    public Crc32(UInt32 polynomial, UInt32 seed)
    {
        table = InitializeTable(polynomial);
        this.seed = seed;
        Initialize();
    }

    public override void Initialize()
    {
        hash = seed;
    }

    protected override void HashCore(byte[] buffer, int start, int length)
    {
        hash = CalculateHash(table, hash, buffer, start, length);
    }

    protected override byte[] HashFinal()
    {
        byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
        this.HashValue = hashBuffer;
        return hashBuffer;
    }

    public override int HashSize
    {
        get { return 32; }
    }

    public static UInt32 Compute(byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
    }

    public static UInt32 Compute(UInt32 seed, byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
    }

    public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
    }

    private static UInt32[] InitializeTable(UInt32 polynomial)
    {
        if (polynomial == DefaultPolynomial && defaultTable != null)
            return defaultTable;

        UInt32[] createTable = new UInt32[256];
        for (int i = 0; i < 256; i++)
        {
            UInt32 entry = (UInt32)i;
            for (int j = 0; j < 8; j++)
                if ((entry & 1) == 1)
                    entry = (entry >> 1) ^ polynomial;
                else
                    entry = entry >> 1;
            createTable[i] = entry;
        }

        if (polynomial == DefaultPolynomial)
            defaultTable = createTable;

        return createTable;
    }

    private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
    {
        UInt32 crc = seed;
        for (int i = start; i < size; i++)
            unchecked
            {
                crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
            }
        return crc;
    }

    private byte[] UInt32ToBigEndianBytes(UInt32 x)
    {
        return new byte[] {
			(byte)((x >> 24) & 0xff),
			(byte)((x >> 16) & 0xff),
			(byte)((x >> 8) & 0xff),
			(byte)(x & 0xff)
		};
    }
}
Code (C#) to extract the three sections of the user data, and process them.
Code:
            using (var stream = new MemoryStream(userData))
            using (var reader = new MiscUtil.IO.EndianBinaryReader(new MiscUtil.Conversion.BigEndianBitConverter(), stream))
            {
                var packetNumber = reader.ReadByte();

                var highDataLength = reader.ReadInt32();
                var highData = reader.ReadBytes(highDataLength);
                if (highDataLength > 0)
                    StatusData.Update(highData);

                var errorString = reader.ReadInt32();

                var lowDataLength = reader.ReadInt32();
                var lowData = reader.ReadBytes(lowDataLength);
                if (lowDataLength > 0)
                    ioData.Update(lowData);
            }
If you have any questions/comments please contact me at eric [at] ehaskins [dot] net, or through the Skype name listed in my profile.
__________________
Eric Haskins KC9JVH

Last edited by EHaskins : 20-04-2010 at 00:29.
  #5   Spotlight this post!  
Unread 26-04-2010, 17:13
byteit101's Avatar
byteit101 byteit101 is offline
WPILib maintainer (WPI)
AKA: Patrick Plenefisch
no team (The Cat Attack (Formerly))
Team Role: Programmer
 
Join Date: Jan 2009
Rookie Year: 2009
Location: Worcester
Posts: 699
byteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of lightbyteit101 is a glorious beacon of light
Re: Status and Error Bytes from Dashboard Packet

hm, i seem to be missing 2 bytes now. using this post, I should have 28 bytes, but counting the image and my code (and a slavik262's db protocol docs), I have 26 bytes accounted for. what are the other two bytes?

http://www.chiefdelphi.com/forums/at...0&d=1232463405
__________________
Bubble Wrap: programmers rewards
Watchdog.Kill();
printf("Watchdog is Dead, Celebrate!");
How to make a self aware robot: while (∞) cout<<(sqrt(-∞)/-0);
Previously FRC 451 (The Cat Attack)
Now part of the class of 2016 at WPI & helping on WPILib
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Dashboard Packet White Paper Out slavik262 Programming 1 04-02-2010 14:49
Dashboard Packet White Paper slavik262 FRC Control System 2 04-02-2010 14:48
Dashboard - User Bytes DanDon Programming 3 20-04-2006 05:10
Dashboard Error Bytes Josh Hambright National Instruments LabVIEW and Data Acquisition 0 16-04-2006 13:32
New dashboard packet spec Ameya Programming 2 08-01-2004 19:59


All times are GMT -5. The time now is 23:20.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi