BallAerospace / COSMOS

Ball Aerospace COSMOS
https://ballaerospace.github.io/cosmos-website/
Other
360 stars 129 forks source link

Using LENGTH Protocol with the sync pattern and CRC #1706

Closed akshatd closed 2 years ago

akshatd commented 2 years ago

I am running COSMOS v5.0.4 and trying to use the LENGTH protocol with the syn pattern with a simple C++ server. However, I cannot figure out from the docs how to add CRC to this.

On the Cosmos side

cmd.txt

COMMAND BOB EXAMPLE LITTLE_ENDIAN "Packet description"
  # Keyword           Name  BitSize Type   Min Max  Default  Description
  APPEND_ID_PARAMETER ID    16      INT    1   1    1        "Identifier"
  APPEND_PARAMETER    VALUE 32      FLOAT  0   10.5 5        "New Value"
  APPEND_PARAMETER    BOOL  8       UINT   MIN MAX  0        "Boolean"
    STATE FALSE 0
    STATE TRUE 1

tlm.txt

TELEMETRY BOB STATUS LITTLE_ENDIAN "Telemetry description"
  # Keyword      Name  BitSize Type   ID Description
  APPEND_ID_ITEM ID    16      INT    1  "Identifier"
  APPEND_ITEM    VALUE 32      FLOAT     "Value"
  APPEND_ITEM    BOOL  8       UINT      "Boolean"
    STATE FALSE 0
    STATE TRUE 1

plugin.txt

# Set VARIABLEs here to allow variation in your plugin
# See https://cosmosc2.com/docs/v5/plugins for more information
VARIABLE bob_target_name BOB

# Modify this according to your actual target connection
# See https://cosmosc2.com/docs/v5/interfaces for more information
TARGET BOB <%= bob_target_name %>
INTERFACE <%= bob_target_name %>_INT tcpip_client_interface.rb host.docker.internal 12345 12345 10.0 nil LENGTH 32 16 0 1 LITTLE_ENDIAN 6 0xBA5EBA11 nil true
  MAP_TARGET <%= bob_target_name %>

Rationale for the LENGTH args:

structs on the C++ server side

#pragma pack(push, 1)
struct PacketHeader {
        uint32_t sync;
        uint16_t len;
};

struct Command {
        PacketHeader hdr;
        int16_t      id;
        float        value;
        uint8_t      boolean;
};

struct Telemetry {
        PacketHeader hdr;
        int16_t      id;
        float        value;
        uint8_t      boolean;
};
#pragma pack(pop)

/* main function and setup socket */

Command cmd;
Telemetry tlm;
sock.read(&cmd, sizeof(Command))
cout << "received: " << cmd.id << ',' << cmd.value << ',' << (int)cmd.boolean << std::endl;

tlm.hdr.sync = 0x11BA5EBA;
tlm.hdr.len  = sizeof(Telemetry);
tlm.id       = 1;
tlm.value   = 5;
tlm.boolean = (uint8_t)tlm.value % 2;

sock.write(&tlm, sizeof(Telemetry);

/* cleanup */

I am stuck here, I cannot figure out how and where to add the CRC, both on COSMOS side and on the C++ side.

Any pointers would be appreciated! Thank you!

jmthomas commented 2 years ago

In the interface documentation we describe Protocols. Have you tried adding our CRC Protocol to your interface:

INTERFACE <%= bob_target_name %>_INT tcpip_client_interface.rb host.docker.internal 12345 12345 10.0 nil LENGTH 32 16 0 1 LITTLE_ENDIAN 6 0xBA5EBA11 nil true
  MAP_TARGET <%= bob_target_name %>
  CRC_PROTOCOL READ CrcProtocol CRC

You would then also have to add a CRC item to your command:

COMMAND BOB EXAMPLE LITTLE_ENDIAN "Packet description"
  # Keyword           Name  BitSize Type   Min Max  Default  Description
  APPEND_ID_PARAMETER ID    16      INT    1   1    1        "Identifier"
  APPEND_PARAMETER    VALUE 32      FLOAT  0   10.5 5        "New Value"
  APPEND_PARAMETER    BOOL  8       UINT   MIN MAX  0        "Boolean"
    STATE FALSE 0
    STATE TRUE 1
  APPEND_PARAMETER  CRC 32 UINT MIN MAX 0 "Packet CRC"

To decode this on the C side you need to implement the CRC algorithm. Our Ruby implementation is here.