Передача запроса на ровер

Для общения с ровером требуется воспользоваться socket.io библиотекой, позволяющей обмениваться данными в реальном времени, реализованной на любом из доступных языков.

В данном документе будет использована версия на языке Python.

Информация необходимая для понимания

Что такое Asyncio?

Asyncio — это библиотека для написания конкурентного кода с использованием синтаксических конструкций async/await.

В частности, этот модуль поддерживает неблокирующую обработку ввода/вывода с использованием подпроцессов (для выполнения команд) и с использованием потоков (для программирования TCP-сокетов).

Что такое корутина/сопрограмма?

Корутина — это функция, выполнение которой можно приостановить и возобновить.

Корутина: корутины — это более общая форма подпрограмм. Подпрограммы имеют одну точку входа и одну точку выхода. А корутины поддерживают множество точек входа, выхода и возобновления их выполнения.

Python glossary

Более подробно о корутинах можно почитать в разделе 2.1. Изменения, внесённые в Python для добавления в язык поддержки корутин.

Добавление пакета в проект

pip install "python-socketio[asyncio_client]"
pip install aiohttp

Создание экземпляра клиента

import socketio
sio = socketio.AsyncClient()

Подключение к серверу

Основные параметры при подключении:

  • url - ip или ссылка на сервер, к которому подключается пользователь для работы с техникой;

  • transports - протокол, по которому происходит общение между клиентом и техникой. В нашем случае мы используем websocket;

  • namespaces - строка или массив строк с названиями "комнат", в которых происходит общение между клиентом и техникой;

  • auth - токен для подключения к серверу. Без него никакие запросы на технику выполнить не получится.

import asyncio
# в зависимости от конфигурации сети, может быть разный ip сервера
server = 'http://192.168.0.1:0000'

async def connection():
    await sio.connect(server, wait_timeout = 5 ,transports='websocket', namespaces=['/vehicles'], auth={"token": ''})

asyncio.run(connection())

Отправка запросов на ровер

Основные параметры при создании запроса:

  • emit_name - название запроса, который пользователь отправляет. Список всех возможных запросов находится в другом разделе;

  • data - данные, которые передаются без параметра. Необязательный параметр;

  • namespace - строка с названиям "комнаты", в которой происходит общение между клиентом и техникой;

  • callback - функция, которая обработает возвращенную информацию.

async def on_message(data):
    print('Получено сообщение:', data)

await sio.emit(`emit_name`, {'data': 'some data'}, namespace=['/vehicles'], callback=on_message)
await sio.emit(`emit_name2`, namespace=['/vehicles'], callback=on_message)

Получение событий

Определение событий

Socket.io основан на событиях, поэтому когда сервер хочет связаться с клиентом, он отправляет событие, которое нужно прослушивать. У каждого события есть имя и список аргументов.

  • name - название события;

  • handler - обработчик вызванного события, в данном примере это on_message;

  • namespace - строка с названиям "комнаты", в которой происходит общение между клиентом и техникой;

async def on_message(data):
    print('Получено сообщение:', data)

sio.on('toClient', on_message, namespace='/vehicles')

Пример команды command на движение

Команда, с громкоговорящим названием command , является общей для большинства действий ровера. В данном блоке мы заставим технику сдвинуться с места и через 5 секунд остановиться.

Параметры данного запроса:

  • name - название события, строка command ;

  • data - данные, которые передаются на ровер:

  1. id - идентификатор техники;

  2. type - тип команды, в данном случае move ;

  3. value - данные для команды move , которые используются для выполнения команды.

Для более подробной информации по value, читайте на вкладке о командах

  • namespace - строка с названиям "комнаты", в которой происходит общение между клиентом и техникой;

  • callback - функция, вызываемая при возвращении результатов выполненя команды.

import socketio
import asyncio
server = 'http://localhost:3006'

# Создаем экземпляр асинхронного клиента Socket.IO
sio = socketio.AsyncClient()

# Определяем обработчик события "connect"
@sio.event
async def connect():
    print('Подключено к серверу Socket.IO')

async def on_move(result):
    print('Command done:', result)
    

async def main():
    # Подключаемся к серверу
    await sio.connect(server, wait_timeout = 20,transports='websocket', namespaces=['/vehicles'], auth={"token": ''})
    await sio.emit('command',{
				'id': 1,
				'type': "move",
				'value': {
					'x': 0,
					'y': 0.5,
					'sensitivity': 1,
				},
			}, namespace='/vehicles', callback=on_move)
    await asyncio.sleep(5)
    await sio.emit('command',{
				'id': 1,
				'type': "move",
				'value': {
					'x': 0,
					'y': 0,
					'sensitivity': 1,
				},
			}, namespace='/vehicles', callback=on_move)
    # Запускаем цикл обработки событий
    await sio.wait()

# Запускаем асинхронный цикл main()
asyncio.run(main())

Last updated