diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e31cfb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +*.user diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..316adb2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "QJoysticks"] + path = QJoysticks + url = https://github.com/alex-spataru/QJoysticks diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a1a9ae..8caacc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,27 +7,28 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_REQUIRED_FLAGS -std=c++17) -set(OpenCV_DIR C:/Libraries/LibOpenCV) - - +find_package(SDL2 REQUIRED) find_package(OpenCV REQUIRED) find_package(Threads) -find_package(Qt5 REQUIRED COMPONENTS +find_package(Qt6 REQUIRED COMPONENTS Core Widgets - SerialPort WebSockets - WebEngine + WebEngineQuick PrintSupport Qml Quick + QuickControls2 Gui - Gamepad Concurrent) + add_executable(${PROJECT_NAME} WIN32 resources/icon.rc) -#add_executable(${PROJECT_NAME} resources/icon.rc) + +file(GLOB QJoystick "${QJoy}/src/*.cpp" "${QJoy}/src/*.h" + "${QJoy}/src/QJoysticks/*.cpp" "${QJoy}/src/QJoysticks/*.h" +) target_sources(${PROJECT_NAME} PRIVATE sources/main.cpp @@ -67,8 +68,6 @@ target_sources(${PROJECT_NAME} PRIVATE sources/RemoteController.hxx PRIVATE sources/QmlImageItem.cpp PRIVATE sources/QmlImageItem.hxx - PRIVATE sources/Gamepad.cpp - PRIVATE sources/Gamepad.hxx PRIVATE sources/EditorIndenter.cpp PRIVATE sources/EditorIndenter.hxx PRIVATE sources/SettingsController.cpp @@ -80,7 +79,11 @@ target_sources(${PROJECT_NAME} PRIVATE sources/HintBase.cpp PRIVATE sources/HintBase.hxx PRIVATE sources/ApiTokenDialog.cpp - PRIVATE sources/ApiTokenDialog.hxx) + PRIVATE sources/ApiTokenDialog.hxx + PRIVATE sources/Joystick.cpp + PRIVATE sources/Joystick.hxx + PRIVATE ${QJoystick} + ) if (WIN32) target_sources(${PROJECT_NAME} @@ -93,18 +96,27 @@ endif() target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) +target_include_directories(${PROJECT_NAME} PRIVATE + ${SDL2_DIR}/include + ${QJoy}/src +) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + SDL_SUPPORTED +) + target_link_libraries(${PROJECT_NAME} - PRIVATE Qt5::SerialPort - PRIVATE Qt5::Core - PRIVATE Qt5::Widgets - PRIVATE Qt5::WebSockets - PRIVATE Qt5::PrintSupport - PRIVATE Qt5::WebEngine - PRIVATE Qt5::Qml - PRIVATE Qt5::Quick - PRIVATE Qt5::Gui - PRIVATE Qt5::Gamepad - PRIVATE Qt5::Concurrent + PRIVATE Qt6::Core + PRIVATE Qt6::Widgets + PRIVATE Qt6::WebSockets + PRIVATE Qt6::PrintSupport + PRIVATE Qt6::WebEngineQuick + PRIVATE Qt6::Qml + PRIVATE Qt6::Quick + PRIVATE Qt6::QuickControls2 + PRIVATE Qt6::Gui + PRIVATE Qt6::Concurrent PRIVATE ${OpenCV_LIBS} + ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/QJoysticks b/QJoysticks new file mode 160000 index 0000000..ccc0f53 --- /dev/null +++ b/QJoysticks @@ -0,0 +1 @@ +Subproject commit ccc0f53d086d3d5f5bc5f1586362b8eaffeb7e2d diff --git a/README.md b/README.md index cebd803..8db000e 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ __[Загрузить (для Windows)](https://murproject.com/documents/17/murI ## Сборка -Инструкции по сборке представлены [на данной странице](https://murproject.github.io/pages/building-mur-ide). +Инструкции по сборке представлены [на данной странице](https://murproject.github.io/pages/building-mur-ide). \ No newline at end of file diff --git a/resources/config/schemes/py.json b/resources/config/schemes/py.json new file mode 100644 index 0000000..c5a8750 --- /dev/null +++ b/resources/config/schemes/py.json @@ -0,0 +1,61 @@ +{ + "scheme": { + "comment": "Python", + "suffixes": ["py"], + "highlight": [{ + "comment": "numbers", + "match": "\\b\\d+(\\.\\d*)?\\b", + "color": "#AF601A", + "bold": true + }, { + "comment": "functions", + "match": "\\b[\\w_]+\\s*(?=\\()", + "color": "#1ABC9C", + "bold": true + }, { + "comment": "keywords", + "match": "(?:\\b|\\s+)(?:(with|yield|del|import|as|global|pass|raise|in|from|try|except|pass))\\b", + "color": "#C678DD", + "bold": true + }, { + "comment": "units", + "match": "(?:\\b|\\s+)(?:(def|class|lambda))\\b", + "color": "#F1948A", + "bold": true + }, { + "comment": "logic", + "match": "(?:\\b|\\s+)(?:(is|not|if|elif|and|or|else|nonlocal))\\b", + "color": "#FFCD02", + "bold": true + }, { + "comment": "boolean", + "match": "(?:\\b|\\s+)(?:(True|False|None|assert))\\b", + "color": "#FC6E51", + "bold": true + }, { + "comment": "controll", + "match": "(?:\\b|\\s+)(?:(finally|return|break|continue|for|while))\\b", + "color": "#5D9CCE", + "bold": true + }, { + "comment": "strings", + "match": "\".*\"", + "color": "#9DA5B4" + }, { + "comment": "single quoted string", + "match": "\'.*\'", + "color": "#9DA5B4" + }, { + "comment": "inline comments", + "match": "#.*$", + "color": "#888", + "italic": true + }, + { + "comment": "multiline comments", + "match": "\"\"\".*\"\"\"", + "color": "#888", + "italic": true + }] + } +} diff --git a/resources/examples/auv_depth_preg.py b/resources/examples/auv_depth_preg.py index c4a4c12..4c80dd1 100644 --- a/resources/examples/auv_depth_preg.py +++ b/resources/examples/auv_depth_preg.py @@ -1,7 +1,7 @@ # Данный пример предназначен для работы на аппарате! # В данном примере реализован простой пропорциональный регулятор по глубине. -# Аппарат убет удерживать заданную глубину 10 секунд. +# Аппарат будет удерживать заданную глубину 10 секунд. import pymurapi as mur diff --git a/resources/examples/auv_led.py b/resources/examples/auv_led.py index 32f2ba8..31a249f 100644 --- a/resources/examples/auv_led.py +++ b/resources/examples/auv_led.py @@ -20,6 +20,6 @@ auv.set_rgb_color(0, 50, 0) time.sleep(3) # Красный - auv.set_rgb_color(0, 50, 0) + auv.set_rgb_color(50, 0, 0) time.sleep(3) diff --git a/resources/examples/auv_moving_average.py b/resources/examples/auv_moving_average.py new file mode 100644 index 0000000..8f3e172 --- /dev/null +++ b/resources/examples/auv_moving_average.py @@ -0,0 +1,57 @@ +# В данном примере реализовано сглаживание тяги методом "простое скользящее среднее" +# Простое скользящее среднее представляет собой сумму последних чисел деленную на их количество. +# Использование скользящего среднего необходимо для плавного увеличения тяги на движителях. + +import pymurapi as mur +import time + +auv = mur.mur_init() + +class MovingAverage: + _storage_size = 50 + + def __init__(self): + self._storage = [0] * self._storage_size + self._counter = 0 + + # Добавление элементов в список + def add(self, value): + self._storage[self._counter] = value + + if(self._counter < (self._storage_size - 1)): + self._counter += 1 + else: + self._counter = 0 + + # Получение среднего арифметического из списка + def get(self): + result = sum(self._storage) / self._storage_size + return result + + # Приравнивание элементов списка нулю + def clean(self): + for i in range(self._storage_size): + self._storage[i] = 0 + + +power1 = MovingAverage() +power2 = MovingAverage() +now = time.time() + +while True: + if (time.time() - now) < 7: + power1.add(-50) + power2.add(100) + elif 7 < (time.time() - now) < 15: + power1.add(50) + power2.add(-100) + else: + power1.add(0) + power2.add(0) + + p1 = power1.get() + p2 = power2.get() + auv.set_motor_power(1, p1) + auv.set_motor_power(2, p2) + + time.sleep(0.1) \ No newline at end of file diff --git a/resources/examples/auv_stream.py b/resources/examples/auv_stream.py new file mode 100644 index 0000000..67d7161 --- /dev/null +++ b/resources/examples/auv_stream.py @@ -0,0 +1,52 @@ +# Пример для версии аппаратов MiddleAUV-CM4 +# Здесь реализована трансляция видео из скрипта +# Данный пример лучше использовать только для тестирования и отладки + +import cv2 as cv +import numpy as np +import pymurapi as mur +from time import sleep + +auv = mur.mur_init() +mur_view = auv.get_videoserver() + +cap0 = cv.VideoCapture(0) +cap1 = cv.VideoCapture(1) + +def find_contours(image, color, approx = cv.CHAIN_APPROX_SIMPLE): + hsv_image = cv.cvtColor(image, cv.COLOR_BGR2HSV) + mask = cv.inRange(hsv_image, color[0], color[1]) + contours, _ = cv.findContours(mask, cv.RETR_CCOMP, approx) + return contours, mask + +def img_process(img, num=0): + font = cv.FONT_HERSHEY_PLAIN + contours, mask = find_contours(img, ((0, 0, 220), (180, 255, 255))) + + if contours: + + for contour in contours: + if cv.contourArea(contour) > 50: + rectangle = cv.minAreaRect(contour) + box = np.int0(cv.boxPoints(rectangle)) + cv.drawContours(img,[box],0,(0,0,250),2) + + cv.putText(img,'Camera {}'.format(num),(5,25),font,2,(255,255,255),2,cv.LINE_AA) + + return img, mask + +while True: + ok, frame0 = cap0.read() +# ok, frame1 = cap1.read() + + frame0 = cv.resize(frame0, (320, 240)) +# frame1 = cv.resize(frame1, (320, 240)) + + result0, mask0 = img_process(frame0, 0) +# result1, mask1 = img_process(frame1, 1) + + mur_view.show(result0, 0) + mur_view.show(mask0, 1) + +mur_view.stop() +print("done") diff --git a/resources/examples/sim_depth_preg.py b/resources/examples/sim_depth_preg.py index b570274..9ea39c9 100644 --- a/resources/examples/sim_depth_preg.py +++ b/resources/examples/sim_depth_preg.py @@ -1,7 +1,7 @@ # Данный пример предназначен для работы в симуляторе! # В данном примере реализован простой пропорциональный регулятор по глубине. -# Аппарат убет удерживать заданную глубину 10 секунд. +# Аппарат будет удерживать заданную глубину 10 секунд. import pymurapi as mur @@ -32,4 +32,4 @@ def keep_depth(depth_to_set): keep_depth(depth) if (time.time() - now) > 15: break - \ No newline at end of file + diff --git a/resources/examples/sim_hsv.py b/resources/examples/sim_hsv.py index 4ac8c92..e658d2a 100644 --- a/resources/examples/sim_hsv.py +++ b/resources/examples/sim_hsv.py @@ -5,7 +5,7 @@ # Функции get_image_front и get_image_bottom работают только в симуляторе. # Для получения видео на аппарате используйте cv2.VideoCapture из OpenCV! -# (https://docs.opencv.org/4.1.1/dd/d43/tutorial_py_video_display.html) +# (https://docs.opencv.org/4.7.0/dd/d43/tutorial_py_video_display.html) import pymurapi as mur diff --git a/resources/examples/sim_test.py b/resources/examples/sim_test.py index bb8ccba..25e3be0 100644 --- a/resources/examples/sim_test.py +++ b/resources/examples/sim_test.py @@ -5,7 +5,7 @@ # Функции get_image_front и get_image_bottom работают только в симуляторе. # Для получения видео на аппарате используйте cv2.VideoCapture из OpenCV! -# (https://docs.opencv.org/4.1.1/dd/d43/tutorial_py_video_display.html) +# (https://docs.opencv.org/4.7.0/dd/d43/tutorial_py_video_display.html) import pymurapi as mur diff --git a/resources/examples/usv_led.py b/resources/examples/usv_led.py deleted file mode 100644 index 12ce0b8..0000000 --- a/resources/examples/usv_led.py +++ /dev/null @@ -1,25 +0,0 @@ -# Данный пример предназначен для работы на аппарате! - -# В данном примере мы устанавливаем цвет RGB ленты -# c периодом включения в 1 секунду и периодом выключения в 0.5 секунды -# на 3 секунды для каждого цвета (синий, зеленый красный) . - - -import pymurapi as mur -import time - -usv = mur.usv_init() - -if __name__ == '__main__': - usv.set_on_delay(1) - usv.set_off_delay(0.5) - # Синий - usv.set_rgb_color(0, 0, 50) - time.sleep(3) - # Зеленый - usv.set_rgb_color(0, 50, 0) - time.sleep(3) - # Красный - usv.set_rgb_color(0, 50, 0) - time.sleep(3) - diff --git a/resources/examples/usv_motors_test .py b/resources/examples/usv_motors_test .py deleted file mode 100644 index 713dac6..0000000 --- a/resources/examples/usv_motors_test .py +++ /dev/null @@ -1,16 +0,0 @@ -# Данный пример предназначен для тестирования моторов на аппарате! - -# В данном примере мы подаем тягу на 4 мотора продолжительностью в 5 секунд. - - -import pymurapi as mur -import time - -usv = mur.usv_init() - -if __name__ == '__main__': - usv.set_motor_power(0, -50) - usv.set_motor_power(1, 50) - usv.set_servo(150) - time.sleep(5) - diff --git a/resources/examples/usv_yaw_preg.py b/resources/examples/usv_yaw_preg.py deleted file mode 100644 index 2f6fbe3..0000000 --- a/resources/examples/usv_yaw_preg.py +++ /dev/null @@ -1,60 +0,0 @@ -# Данный пример предназначен для работы на аппарате! - -# В данном примере реализован простой пропорциональный регулятор по курсу. -# Аппарат будет плыть прямо с тягой в 25%, удерживая изначальный курс, 10 секунд. - -import pymurapi as mur -import cv2 as cv -import time - -usv = mur.usv_init() - -# Перевод угла из -180 <=> 180 в 0 <=> 360 -def to_360(angle): - if angle > 0.0: - return angle - if angle <= 0.0: - return 360.0 + angle - -# Перевод угла >< 360 в 0 <=> 360 -def clamp_to_360(angle): - if angle < 0.0: - return angle + 360.0 - if angle > 360.0: - return angle - 360.0 - return angle - -# Перевод угла из 0 <=> 360 в -180 <=> 180 -def to_180(angle): - if angle > 180.0: - return angle - 360.0 - return angle - -# Преобразовать v в промежуток между min max -def clamp(v, min, max): - if v < min: - return min - if v > max: - return max - return v - -# Функция удержания курса -def keep_yaw(yaw_to_set, power): - current_yaw = to_360(auv.get_yaw()) - er = clamp_to_360(yaw_to_set - current_yaw) - er = to_180(er) - res = er * 0.7 - usv.set_motor_power(0, clamp(int(power - res), -100, 100)) - usv.set_motor_power(1, clamp(int(power + res), -100, 100)) - - -if __name__ == '__main__': - time.sleep(0.5) - yaw = to_360(usv.get_yaw()) - now = time.time() - while True: - keep_yaw(yaw, -25) - if (time.time() - now) > 10: - break - - diff --git a/resources/fonts/NotoMono-Regular.ttf b/resources/fonts/NotoMono-Regular.ttf new file mode 100644 index 0000000..3560a3a Binary files /dev/null and b/resources/fonts/NotoMono-Regular.ttf differ diff --git a/resources/fonts/NotoSans-Bold.ttf b/resources/fonts/NotoSans-Bold.ttf new file mode 100644 index 0000000..f95a702 Binary files /dev/null and b/resources/fonts/NotoSans-Bold.ttf differ diff --git a/resources/fonts/NotoSans-Regular.ttf b/resources/fonts/NotoSans-Regular.ttf new file mode 100644 index 0000000..7da1a0f Binary files /dev/null and b/resources/fonts/NotoSans-Regular.ttf differ diff --git a/resources/help/help.html b/resources/help/help.html index f770821..dc9988f 100644 --- a/resources/help/help.html +++ b/resources/help/help.html @@ -1,1852 +1,397 @@ - - -
- -Интерфейс murIDE состоит из 10 основных элементов:
Все просто - вам нужно включить аппарат, подождать пока появится WiFi (murAP), подключится к нему (пароль по умолчанию vladivostok) и... Все готово!
Запустить симулятор еще проще - достаточно нажать кнопку "Запуск симулятора" и подождать пока он откроется. Симулятор программируется точно так же как и аппарат, за исключением пары функций из pymurapi.
Важно: вы не можете управлять LED лентой в симуляторе. Для получения изображений из симулятора есть специальные функции
get_image_front
иget_image_bottom
, данные функции НЕ работают на аппарате. Для получения видеоизображений воспользуйтесь функциями из OpenCV . Так же важно отметить, формат некоторых данных различен (показания курса, глубины). Имейте это ввиду.
Первым делом вам необходимо подключить библиотеку pymurapi. Для того, чтобы это сделать вызовите следующий код:
xxxxxxxxxx
import pymurapi as mur
В дальнейшем mur будет использоваться в качестве алиаса на библиотеку pymurapi.
Далее вам необходимо создать экземпляр объекта MurApiBase. Для этого вызовите функцию mur_init():
xxxxxxxxxx
auv = mur.mur_init()
Важно: Функция mur_init должна быть вызвана только один раз! Множественные вызовы данной функции ведут к неопределенному поведению.
Все готово! Библиотека pymurapi подключена и инициализирована. Вся дальнейшая работа с аппаратом или симулятором будет происходить через объект auv.
def set_on_delay(value)
# C помощью данной функции вы можете задать время, которое будет гореть LED лента на аппарате.
# Данная функция работает только на аппарате.
# Время задается в секундах.
# Пример использования:
auv.set_on_delay(0.5)
xxxxxxxxxx
def set_off_delay(value)
# C помощью данной функции вы можете задать время, которое LED лента гореть не будет.
# Данная функция работает только на аппарате.
# Время задается в секундах.
# Пример использования:
auv.set_off_delay(1.8)
xxxxxxxxxx
def set_rgb_color(r, g, b):
# C помощью данной функции вы можете задать цвет LED ленты в цветовом пространстве RGB.
# Данная функция работает только на аппарате.
# Пример использования:
auv.set_rgb_color(128, 0, 64)
xxxxxxxxxx
def set_motor_power(motor_id, power)
# C помощью данной функции вы можете задать тягу на моторы от -100 до 100. Где motor_id - номер мотора от 0 до 5 для аппарата и от 0 до 3 для симулятора.
# Пример использования:
auv.set_motor_power(0, 50)
auv.set_motor_power(1, -50)
Важно: В симуляторе моторы 0 и 1 отвечают за движение вперед/назад. Мотор 2 и 3 за всплытие/погружение. Мотор 4 за движение влево/вправо.
xxxxxxxxxx
def get_depth()
# Данная функция возвращает значение глубины.
# Пример использования:
depth = auv.get_depth()
xxxxxxxxxx
def get_yaw()
# Данная функция возвращает значение курса.
# Пример использования:
yaw = auv.get_yaw()
xxxxxxxxxx
def get_pitch()
# Данная функция возвращает значение крена.
# Пример использования:
pitch = auv.get_pitch()
xxxxxxxxxx
def get_roll()
# Данная функция возвращает значение диффирента.
# Пример использования:
roll = auv.get_roll()
Важно: Функции, приведенные ниже, доступны только в симуляторе, на аппарате данный код работать НЕ будет. Мы вас предупредили.
xxxxxxxxxx
def get_image_front()
# Даная функция возвращает изображение с передней камеры - тип cv2.Mat (BGR, CV8_UC3).
# Данная функция работает только в симуляторе.
# Пример использования:
image = auv.get_image_front()
x
def get_image_bottom()
# Даная функция возвращает изображение с донной камеры - тип cv2.Mat (BGR, CV8_UC3).
# Данная функция работает только в симуляторе.
# Пример использования:
image = auv.get_image_front()
xxxxxxxxxx
def drop()
# Вызов данный функции приведет к сбросу сферического объектов в симуляторе.
auv.drop()
x
def shoot()
# Вызов данный функции приведет к выстрелу целиндрическим объектов в симуляторе.
auv.shoot()
x
def open_grabber()
# Вызов данный функции приведет к раскрытию захвата в симуляторе.
auv.open_grabber()
x
def close_grabber()
# Вызов данный функции приведет к закрытию захвата в симуляторе.
# Если в момент вызова захвата находился в контакте с объектом, то объект будет "захвачен".
auv.close_grabber()
x
def get_pinger_data(pinger_id):
# Данная функция возвращает угол и расстояния до гидроакустического маяка на сцене.
# Всего может быть до четырех маяков в одной сцене.
# Аргументом данной функции является ID маяка (0, 1, 2 или 3).
# Если маяк с таким ID на сцене отсутствует - данная функция вернет 0, 0.
# Маяки имеют определенную частоту обновления. По умолчанию частота обновления значений установлена в 2000 миллисекунд.
# Значение частоты обновления может быть изменено в настройках симулятора.
angle, distance = auv.get_pinger_data(0)
angle, distance = auv.get_pinger_data(3)
Интерфейс MUR IDE состоит из 10 основных элементов:
+ +Все просто - вам нужно включить аппарат, подождать пока появится WiFi (mur_ssid), подключиться к нему (пароль по умолчанию vladivostok) и... Все готово!
+В информационной вкладке Remote [10] отображается видео с камер аппарата. Видео можно записать (кнопка Record), а так же сделать фото (кнопка Capture). Сделанные фото и видео сохраняются на диске, куда установлена программа: C:\Users\User_name\Pictures\murImages
+Если у вас возникли проблемы с получением изображения с аппарата, то Вам необходимо отключить Брандмауэр Windows.
+Для телеуправления аппаратом с помощью клавиатуры необходимо нажать на информационную вкладку Remote [10], раскрыть меню Gamepad axes и нажать на появившуюся область.
+Теперь вы можете управлять аппаратом с помощью кнопок W, A, S, D, Q, E.
+Запустить симулятор еще проще - достаточно нажать кнопку "Запуск симулятора" и подождать пока он откроется. Симулятор программируется точно так же как и аппарат, за исключением пары функций из pymurapi.
+++Важно: вы не можете управлять LED лентой в симуляторе. Для получения изображений из симулятора есть специальные функции get_image_front и get_image_bottom, данные функции НЕ работают на аппарате. Для получения видеоизображений воспользуйтесь функциями из OpenCV. Так же важно отметить, формат некоторых данных различен (показания курса, глубины). Имейте это ввиду.
+
Первым делом вам необходимо подключить библиотеку pymurapi. Для того, чтобы это сделать вызовите следующий код:
+import pymurapi as mur
+
+В дальнейшем mur будет использоваться в качестве алиаса на библиотеку pymurapi.
+Далее вам необходимо создать экземпляр объекта MurApiBase. Для этого вызовите функцию mur_init():
+auv = mur.mur_init()
+
+++Важно: Функция mur_init должна вызываться только один раз! Множественные вызовы данной функции ведут к неопределенному поведению.
+
Все готово! Библиотека pymurapi подключена и инициализирована. Вся дальнейшая работа с аппаратом или симулятором будет происходить через объект auv.
+def set_on_delay(value)
+# C помощью данной функции вы можете задать время, которое будет гореть LED лента на аппарате.
+# Данная функция работает только на аппарате.
+# Время задается в секундах.
+# Пример использования:
+auv.set_on_delay(0.5)
+
+def set_off_delay(value)
+# C помощью данной функции вы можете задать время, которое LED лента гореть не будет.
+# Данная функция работает только на аппарате.
+# Время задается в секундах.
+# Пример использования:
+auv.set_off_delay(1.8)
+
+def set_rgb_color(r, g, b):
+# C помощью данной функции вы можете задать цвет LED ленты в цветовом пространстве RGB.
+# Данная функция работает только на аппарате.
+# Пример использования:
+auv.set_rgb_color(128, 0, 64)
+
+def set_single_led_color(led, r, g, b):
+# C помощью данной функции вы можете задать цвет отдельных светодиодов на LED ленте в цветовом пространстве RGB.
+# Данная функция работает только на аппаратах MiddleAUV выпущенных мая 2021 года и позже.
+# На LED ленте 13 светодиодов. 0 - это номер первого светодиода, 12 - последнего.
+# Пример использования:
+auv.set_single_led_color(12, 128, 0, 64)
+
+def set_motor_power(motor_id, power)
+# C помощью данной функции вы можете задать тягу на моторы от -100 до 100. Где motor_id - номер мотора от 0 до 5 для аппарата и от 0 до 3 для симулятора.
+# Пример использования:
+auv.set_motor_power(0, 50)
+auv.set_motor_power(1, -50)
+
+++Важно: В симуляторе моторы 0 и 1 отвечают за движение вперед/назад. Мотор 2 и 3 за всплытие/погружение. Мотор 4 за движение влево/вправо.
+
def get_depth()
+# Данная функция возвращает значение глубины.
+# Пример использования:
+depth = auv.get_depth()
+
+def get_yaw()
+# Данная функция возвращает значение курса.
+# Пример использования:
+yaw = auv.get_yaw()
+
+def get_pitch()
+# Данная функция возвращает значение крена.
+# Пример использования:
+pitch = auv.get_pitch()
+
+def get_roll()
+# Данная функция возвращает значение дифферента.
+# Пример использования:
+roll = auv.get_roll()
+
+++Важно: Функции, приведенные ниже, доступны только в симуляторе, на аппарате данный код работать НЕ будет. Мы вас предупредили.
+
def get_image_front()
+# Даная функция возвращает изображение с передней камеры - тип cv2.Mat (BGR, CV8_UC3).
+# Данная функция работает только в симуляторе.
+# Пример использования:
+image = auv.get_image_front()
+
+def get_image_bottom()
+# Даная функция возвращает изображение с донной камеры - тип cv2.Mat (BGR, CV8_UC3).
+# Данная функция работает только в симуляторе.
+# Пример использования:
+image = auv.get_image_bottom()
+
+def drop()
+# Вызов данной функции приведет к сбросу сферического объекта в симуляторе.
+auv.drop()
+
+def shoot()
+# Вызов данной функции приведет к выстрелу цилиндрическим объектом в симуляторе.
+auv.shoot()
+
+def open_grabber()
+# Вызов данной функции приведет к раскрытию захвата в симуляторе.
+auv.open_grabber()
+
+def close_grabber()
+# Вызов данной функции приведет к закрытию захвата в симуляторе.
+# Если в момент вызова захвата находился в контакте с объектом, то объект будет "захвачен".
+auv.close_grabber()
+
+def get_hydrophone_signal():
+# Данная функция возвращает сигналы с трех гидрофонов и расстояние каждого из них до гидроакустического маяка на сцене.
+# Гидрофоны располагаются на переднем правом, переднем левом и на заднем правом моторе. В таком же порядке данная функция и возвращает значения.
+# Каждый из гидрофонов передает информацию о том, какой маяк транслирует сигнал. Номер маяка соответствует цифре сигнала (от 1 до 5).
+# Всего может быть до пяти маяков на одной сцене.
+# В настройках симулятора доступны изменения некоторых параметров транслируемого сигнала. Pulse period - период импульса, pulse width - ширина импульса, spreading speed - скорость распространения сигнала.
+tr, tl, fr, dist_tr, dist_tl, dist_fr = auv.get_hydrophone_signal()
+
+
+
+
+
+