Robotics/IOT .NET Core

Дисклеймер


Используемые библиотеки и приложения

Наименование Применение
Библиотеки
MessagePack Используется для сериализации/десериализации сообщений между клиентом и роботом
Serilog Используется для логирования информации и сохранения ее в базу данных
LiteDB NoSQL-хранилище для хранения логов
System.Device.GPIO Библиотека для работы с IOT
NetMQ Библиотека для работы с библиотекой ZeroMQ. Используется для TCP-сокетов
nanoFramework Библиотека для написания кода на C# для IOT
Приложения
LiteDB.Studio Приложение для просмотра и редактирования LiteDB

Общая схема работы проекта

scheme

  1. Робот подключается к WiFi и получает сетевые настройки.
  2. Пользователь Master подключается к WiFi сетевые настройки.
  3. Пользователь Master запускает приложение для установления сетевого соединения с роботом. В приложении:
    2.1 Производится станирование сети
    2.2 В случае успешного нахождения устройства, производится подключение к нему
  4. После успешного установления сетевого соединения идет обмен данными в режиме реального времени и логирование данных в черный ящик

Хранение данных

В качестве системы хранения данных (логирование), используется NoSQL-хранилище (LiteDB)

Суммарно, хранится три сессии данных, остальные удаляются ввиду отсутствия какой-либо необходимости и с целью сохранить память на MicroSD.


Схема взаимодействия

communication

Передача и получение трафика производятся с использованием ZeroMQ с использованием Pair Socket

В предыдущей версии использовался принцип Pull/Push, где в роли получающего был непосредственно робот, но, ввиду того, что я решил направлять данные в обе стороны, было принято отказаться от данного подхода


Протокол обмена данными

Обмен данными между клиентом и сервером осуществляется посредством передачи IEnumerable<byte> друг с другом по следующей схеме, реализованной в файле MessagesExtension.cs:

var bytesList = new List<byte[]>
{
    identifyModel.Serialize(), // RoboIdentifier or ClientIdentifier
    Array.Empty<byte>(), // Always empty array
    new [] { (byte) type }, // Always MessageType casted to byte
    Array.Empty<byte>(), // Always empty array
    MessagePackSerializer.Serialize(model) // Workload model
    // ... another serialization of workload
};

Основной алгоритм обработки полученных сообщений выглядит следующим образом:

  1. Производится попытка получить сообщение из потока
  2. Производится сверка количества полученных "кадров" в рамках одного сообщения

2.1. Если количество кадров меньше 3, это считается неполным сообщением, будет сообщение об ошибке.
2.2. Если кадр с первым индексом будет чем-то заполнен, это считается нарушением протокола. Будет сообщение об ошибке.
2.3. Если десериализованная модель клиента или десериализованный тип будут иметь значение null, это считается нарушением целостности данных, будет выведена ошибка.

  1. Производится сверка количества кадров, если их количество менее трех и менее пяти, обработка кадров будет считаться оконченной.
  2. Если количество символов в четвертом кадре будет более нуля, это считается нарушением протокола, будет сообщение об ошибке.
  3. Все дальнейшие кадры будут в цикле десериализованны, согласно полученному MessageType из второго кадра и будут произведены действия, которые соответствуют модели данных.