First and foremost, please use a decent IDE. You hearing, Armin?
+
+
I tried to shove documentation wherever possible, so that the IDE can give some hints of the type and the meaning of the variables. To do that, just hover your mouse over the thing you want some information. It may not always be helpful, but at least I tried. Also, the code is almost all type annotated, which may also help.
The installed package contains 4 submodules, that can be divided in two groups, plus a module that will be generated locally. However, normally, you should only need pyimclsts.network and the module generated by pyimclsts.extract.
+
+
+
Message extraction/generation:
+
+
pyimclsts.extract
+It is intended to be executed to generate python classes that represent messages.
+
pyimclsts.extractutils
+Contains some useful functions to analyze the IMC.xml file.
+
+
+
Networking:
+
+
pyimclsts.core
+Contains functions that support the network operations, such as serialization/deserialization and the CRC16 algorithm.
+
pyimclsts.network
+Contains functions that allow reading and writing messages in a stream fashion, namely, the subscriber function.
+
+
+
+
+
Lastly, when the pyimclsts.extract is run with python3 -m pyimclsts.extract, it creates a folder containing the IMC messages as classes, as well as other supporting data types, such as enumerations, and bitfields. It should look like this:
+
+
+
pyimc_generated
+
+
__init__.py
+
_base.py
+
bitfields.py
+
categories
+
+
AcousticCommunication.py
+
Actuation.py
+
…
+
+
+
enumerations.py
+
messages.py
+
+
+
+
+
enumerations.py and bitfields.py contain globally (in the IMC.xml) defined enumerations and bitfields (locally defined enumerations or bitfields are stored inside the corresponding message class). messages.py re-exports the messages defined in their corresponding category file. It re-exports, for example, the Announce message, found in categories/Networking.py.
There are three main elements in this model: a subscriber, a publisher and a message bus. In short, a publisher application writes messages to a shared interface, also known as the message bus, and a subscriber application register with the broker the messages it wants to consume. So, in order to comply with this model, we need a message broker to receive messages from the network, execute the subscribed functions, and also distribute the messages. Additionally, the subscriber functions should be able to have state, run independently (not creating deadlocks nor race conditions), and send and receive messages.
The IMC establishes a common control message set understood by all LSTS nodes. It was developed at the LSTS and it is pervasive in the LSTS ecosystem, as it enables communication among interconnected systems of vehicles, sensors, DUNE tasks, and even other layers of the control architecture, such as the Neptus.
+
+
IMC abstracts hardware and communication differences, providing a shared set of messages that can be serialized and then exchanged using various means. Unlike other protocols, IMC does not impose a specific software architecture, allowing for native support generation across different programming languages and computer architectures. The message specification is an XML file that can be found in the repository of the LSTS. It should contain all the necessary information to serialize and deserialize messages exchanged in the network.
Synchronization Number (16 bit unsigned integer): Used to mark the begin of a message in the byte stream;
+
Message Identification Number (16 bit unsigned integer): Determines which messages this byte stream contains;
+
Message size (16 bit unsigned integer): Number of bytes of the ``Fields’’ part of the message;
+
Timestamp (64 bit double precision floating point number in IEEE 754 format): The time when the message was sent. The number of seconds is represented in Universal Coordinated Time (UCT) in seconds since Jan 1, 1970;
+
Source Address (16 bit unsigned integer): The number that identify, within the IMC network, the system that created this message;
+
Source Entity (8 bit unsigned integer): The entity (in general, a Dune task) generating this message at the source address.
+
Destination Address (16 bit unsigned integer): The number that identify, within the IMC network, the target system of this message;
+
Destination Entity (8 bit unsigned integer): The number that identify, within the IMC network, the target entity of this message, within the target system;
The payload of the message. A finite set of values that carry information according to the definition of the container message. In particular, it can be of any type specified in the IMC schema, including another message or a list thereof;
A checksum value, calculated using the CRC-16-IBM with polynomial 0x8005 ((x^16 + x^15 + x^2 + 1)), that validates and indicates the integrity of the message;
To ensure accurate transportation, some field types may require special treatment on transmission and reception. The operation of preparing a field type for transmission is called serialization, the inverse action is called deserialization. No special process is required for native types, such as integers, floating points and unsigned integers. For “composite” types, we use:
+
+
+
+
rawdata
+rawdata is serialized by prepending a value of type uint16_t, representing the length of the sequence, to the stream of bytes. On deserialization the prepended value is used to retrieve the length of the byte sequence.
+
+
+
plaintext
+plaintext is serialized by prepending a value of type uint16_t, representing the length of the sequence, to the stream of ASCII characters. On deserialization the prepended value is used to retrieve the length of the ASCII character sequence.
+
+
+
message
+message is serialized by prepending a value of type uint16_t, representing the identification number of the message, to the serialized message payload. The special identification number 65535 must be used when no message is present. On deserialization the prepended value is used to retrieve the correct message identification number.
+
+
+
message-list
+message-list is serialized by prepending a value of type uint16_t, representing the number of messages in the list, to the serialized message payload. On deserialization the prepended value is used to retrieve the correct number of messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/_site/feed.xml b/docs/_site/feed.xml
new file mode 100644
index 0000000..d68e61e
--- /dev/null
+++ b/docs/_site/feed.xml
@@ -0,0 +1 @@
+Jekyll2023-10-08T00:20:27+01:00http://localhost:4000/feed.xmlPyIMCLSTS DocumentationPython bindings for the IMC message protocol of the LSTS toolchain.
\ No newline at end of file
diff --git a/docs/_site/index.html b/docs/_site/index.html
new file mode 100644
index 0000000..01cd270
--- /dev/null
+++ b/docs/_site/index.html
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+
+
+
+
+
+PyIMCLSTS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Choose a folder and have a version of the IMC schema, that is, a file named IMC.xml. Otherwise, it will automatically fetch the latest IMC version from the LSTS git repository. Just run:
+
$ python3 -m pyimclsts.extract
+
+
+
This will locally extract the IMC.xml as Python classes. You will see a folder called pyimc_generated which contains base messages, bitfields and enumerations from the IMC.xml file. They can be locally loaded using, for example:
By creating messages locally and installing only the shared functions, it is possible to work with different versions of the IMC on the same Python environment.