VBCores Документация
СайтGitHub
  • VBCores
  • Hardware
    • VBCore VB32G4
    • VB STM32 программатор
    • BLDC драйвер 30A
    • DC драйвер 15A
    • Stepper драйвер 10A
    • CAN-FD - Raspberry PI
      • Настройка CAN на RPI
      • Часто возникаемые ошибки при работе с CAN/CAN FD
      • Работа с CAN FD через Python
    • Power board 30A
    • SBus-HID
    • DC-DC преобразователь
    • Ethernet - CAN-FD
    • USB-HUB
    • IMU BNO055
    • IMU BHI360
    • Т-Энкодер
  • Настройка ПО
    • Arduino IDE
      • Подготовка модуля VBCore
      • Установка среды программирования на Windows
      • Установка среды программирования на Ubuntu
        • Возможные ошибки в Ubuntu при работе с Arduino
      • Выбор платы в Arduino IDE
      • Установка базовой библиотеки
      • Структура ПО для Arduino
      • Примеры
        • Работа с CAN и CAN FD на Arduino
        • Работа с I2C
        • I2C detect
        • Датчик BNO055 / I2C
        • Датчик AS5047P / SPI
        • Датчик AS5600 / I2C
        • Работа с бесколлекторными двигателями
          • Simple FOC. Управление скоростью. Нахождение количества пар полюсов.
          • Simple FOC. Управление моментом
          • Чтение данных с датчика тока
        • Работа с коллекторным двигателем
          • Вращение DC мотором
          • Чтение угла по энкодеру. Управление DC мотором по углу
          • Чтение скорости вращения мотора по энкодеру
        • Работа с шаговым двигателем
          • Вращение шагового двигателя.
          • Контроль двигателя по интерфейсу SPI
    • STM32 CUBE IDE
      • Типовые настройки
      • Подсказки начинающим
        • Cube IDE для начинающих
        • Clock configuration
        • Таймеры - прерывания
        • Таймеры - ШИМ
        • Отладка программ
        • Коммуникации - FDCAN
        • Управление DC-мотором
        • Backup программы
  • Cyphal CAN
    • Cyphal CAN
    • PyCyphal
    • Yakut
    • Cyphal Arduino
      • Отправка и получение сообщений по cyphal
  • Работа с ROS
    • Установка Ubuntu, ROS и Arduino
    • ROS_LIB
    • Примеры
      • Publisher. Hello World!
      • Publisher with Subscriber
      • Rotation by DC motor
  • Работа с научным ПО
    • TCP Server
    • LabView
    • Matlab
  • Инструкции
    • Стенд управления двигателями
    • Переделка датчика мотор-колеса
    • Стенд мотор-колеса
    • iPower Motor
    • AS5047p OEM
  • Практические занятия
    • Коллекторный двигатель
      • Устройство коллекторного двигателя
  • RPI Display
Powered by GitBook
On this page
  1. Cyphal CAN

PyCyphal

Работа с Cyphal на Python

PreviousCyphal CANNextYakut

Last updated 3 months ago

Работать с cyphal на питоне можно с помощью библиотеки .

Мы также написали на python класс, умеющий, отправлять и получать сообщения по cyphal can по заранее заданным ID, его можно найти в отдельном

Здесь же рассмотрим пример класса Controller, в котором реализован паблишер и сабскрайбер. Паблишер будет отправлять напряжение (в вольтах), которое рассчитывается исходя из угла датчика мотора, получаемого сабскрайбером.

Программа, написанная на ардуино, которая публикует значение угла датчика мотора и подает в качестве управляющего воздействия напряжение, получаемое "сверху", находится в примерах на ардуино - ControlVoltage_SendAngle_cyphal

Само приложение Cyphal зависит от стандартных определений DSDL, расположенных в пространстве имен uavcan. Стандартное пространство имен является частью регламентированных пространств имен, поддерживаемых проектом OpenCyphal. Скачайте его с github:

git clone https://github.com/OpenCyphal/public_regulated_data_types

И укажите в файле .bashrc путь к пространству имен.

sudo nano .bashrc
export CYPHAL_PATH="$HOME/public_regulated_data_types"

CYPHAL_PATH должен содержать список всех путей, по которым должны находиться корневые каталоги пространства имен DSDL

Подробнее об этом в

import pycyphal
import pycyphal.application
from pycyphal.application import heartbeat_publisher
import uavcan.si.unit.voltage  
import uavcan.si.sample.angle
import uavcan.node
import asyncio
import os
import sys


def sign(x):
    if x>0:
        return 1
    elif x<0:
        return -1
    else:
        return 0


class Controller:
    REGISTER_FILE = "controller.db"

    def __init__(self) -> None:
        node_info = uavcan.node.GetInfo_1.Response(
            software_version=uavcan.node.Version_1(major=1, minor=0),
            name="org.opencyphal.pycyphal.cyphal_test",
        )
        self.voltage_output = 0
        self._node = pycyphal.application.make_node(node_info, Controller.REGISTER_FILE)
        self._node.heartbeat_publisher.mode = uavcan.node.Mode_1.OPERATIONAL  # type: ignore
        self._node.heartbeat_publisher.vendor_specific_status_code = os.getpid() % 100
       

        self._sub_ang = self._node.make_subscriber(uavcan.si.sample.angle.Scalar_1, 1111)
        self._pub_volt = self._node.make_publisher(uavcan.si.unit.voltage.Scalar_1, 1112)
        
        self._node.start()

    def close(self) -> None:
        """
        This will close all the underlying resources down to the transport interface and all publishers/servers/etc.
        All pending tasks such as serve_in_background()/receive_in_background() will notice this and exit automatically.
        """
        self._node.close()

    async def run(self) -> None:
        """
        The main method that runs the business logic. It is also possible to use the library in an IoC-style
        by using receive_in_background() for all subscriptions if desired.
        """
        angle_setpoint = 0.0
        async for m, _metadata in self._sub_ang:
            assert isinstance(m, uavcan.si.sample.angle.Scalar_1)
            print("angle:",m.radian)
            err = angle_setpoint - m.radian
            self.voltage_output = -5*sign(err)
            await self._pub_volt.publish(uavcan.si.unit.voltage.Scalar_1(self.voltage_output))
            


async def main() -> None:
    #logging.root.setLevel(logging.INFO)
    app = Controller()
    try:
        await app.run()
    except KeyboardInterrupt:
        pass
    finally:
        app.close()


if __name__ == "__main__":
    asyncio.run(main())
  
PyCyphal
репозитории
документации