I wrote a program that controls an OpenDMX controller (Enttec OpenDMX controller), but I'm getting an error.
an error appears when selecting a target
Ошибка в цикле: 'OpenDMXController' object has no attribute 'set_channel'
Please help
Code:
import socket
import json
import struct
import math
import time
from PyDMXControl.controllers import OpenDMXController
# ==========================================
# 1. НАСТРОЙКИ ПОДКЛЮЧЕНИЯ
# ==========================================
# Мы подключаемся к stracker.py, который работает на этом же компьютере
SERVER_IP = '127.0.0.1'
SERVER_PORT = 65432
# ==========================================
# 2. НАСТРОЙКИ СЦЕНЫ И КАМЕРЫ
# ==========================================
# Важно! Расстояние от проектора до сцены (в сантиметрах)
DISTANCE_TO_STAGE = 300.0
# Разрешение камеры (нужно для поиска центра кадра)
# Обычно Jetson использует 1280x720. Если у вас другое - поменяйте.
CAMERA_WIDTH = 1280
CAMERA_HEIGHT = 720
# ==========================================
# 3. НАСТРОЙКИ КАНАЛОВ (ПО ВАШЕМУ ФОТО)
# ==========================================
# Таблица из инструкции:
# 1: Pan (Горизонт)
# 2: Pan Fine (Тонкая) - пропускаем
# 3: Tilt (Вертикаль)
# 4: Tilt Fine (Тонкая) - пропускаем
# 5: Color (Цвет)
# 7: Strobe (Строб)
# 8: Dimmer (Яркость)
CH_PAN = 1
CH_TILT = 3
CH_COLOR = 5
CH_STROBE = 7
CH_DIMMER = 8
# Максимальные углы поворота головы (обычно 540 и 270)
MAX_PAN_ANGLE = 540.0
MAX_TILT_ANGLE = 270.0
# ==========================================
# 4. ИНИЦИАЛИЗАЦИЯ DMX
# ==========================================
print("--- ЗАПУСК DMX КЛИЕНТА ---")
print("Поиск контроллера OpenDMX...")
try:
\# Инициализация контроллера Enttec Open DMX
dmx = OpenDMXController()
print("\>\> Контроллер успешно подключен!")
кроме исключения как e:
print(f"\>\> ОШИБКА подключения контроллера: {e}")
print("Проверьте, подключен ли USB кабель и есть ли права (sudo).")
exit()
def set_dmx_val(канал, значение):
"""Безопасная отправка значения (0-255)"""
safe_val = max(0, min(255, int(value)))
dmx.set_channel(channel, safe_val)
# ==========================================
# 5. ФУНКЦИИ СЕТИ (Чтение протокола stracker.py)
# ==========================================
def recvall(sock, n):
"""Помощник: читать ровно n байт"""
data = bytearray()
while len(data) \< n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
def Recv_msg(sock):
"""Чтение сообщения с 4-байтовым заголовком длины (как в stracker.py)"""
\# 1. Читаем 4 байта (длина сообщения)
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
\# 2. Распаковываем длину (big-endian integer)
msglen = struct.unpack('\>I', raw_msglen)\[0\]
\# 3. Читаем само сообщение
return recvall(sock, msglen)
# =======================================
# 6. МАТЕМАТИКА (Координаты -> Углы)
# ========================================================(c>def Calculate_dmx_gls(cam_x, cam_y):\# 1. Находим отклонение от центра кадра в пикселях
\# Если cam_x = 640 (центр), то offset_x = 0
offset_x = cam_x - (CAMERA_WIDTH / 2)
\# Инверсия Y (часто камеры видят верх как 0, а проекторы низ как 0)
\# Если нужно инвертировать движение по вертикали, поменяйте знак
offset_y = cam_y - (CAMERA_HEIGHT / 2)
\# 2. Считаем угол через арктангенс
\# math.atan возвращает радианы, переводим в градусы
angle_x = math.degrees(math.atan(offset_x / DISTANCE_TO_STAGE))
angle_y = math.degrees(math.atan(offset_y / DISTANCE_TO_STAGE))
\# 3. Переводим угол в DMX (0-255)
\# 128 - это центр (0 градусов)
pan_dmx = 128 + (angle_x \* (255 / MAX_PAN_ANGLE))
tilt_dmx = 128 + (angle_y \* (255 / MAX_TILT_ANGLE))
return int(pan_dmx), int(tilt_dmx)
# ==========================================
# 7. ОСНОВНОЙ ЦИКЛ
# ==========================================
def main():
while True:
try:
print(f"Подключение к stracker.py ({SERVER_IP}:{SERVER_PORT})...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, SERVER_PORT))
print("\>\> Соединение установлено! Ожидание данных...")
while True:
\# Получаем JSON от stracker.py
data_bytes = recv_msg(s)
if not data_bytes:
print("Сервер закрыл соединение.")
break
\# Декодируем
json_str = data_bytes.decode('utf-8')
targets = json.loads(json_str) # Это список \[...\]
\# Проверяем, есть ли кого отслеживать
\# stracker.py отправляет список, нам нужен тот, у кого 'State' или просто первый
if len(targets) \> 0:
\# Берем первую цель из списка (обычно это TargetID)
target = targets\[0\]
x = target.get('CenterX', 0)
y = target.get('CenterY', 0)
state = target.get('State', 0) # 1 - красный (вкл), 0 - зеленый (выкл)
\# --- 1. Движение ---
pan, tilt = calculate_dmx_angles(x, y)
set_dmx_val(CH_PAN, pan)
set_dmx_val(CH_TILT, tilt)
\# --- 2. Управление светом ---
\# На фото: Ch7 Strobe, Ch8 Dimmer.
\# Чтобы светило: Strobe=0 (без мигания), Dimmer=255.
\# Чтобы выключить: Dimmer=0.
if state == 1:
\# ВКЛЮЧИТЬ (Красный режим в трекере)
set_dmx_val(CH_COLOR, 0) # Белый цвет (0-139)
set_dmx_val(CH_STROBE, 0) # Строб открыт/выключен
set_dmx_val(CH_DIMMER, 255)# Яркость на полную
else:
\# ВЫКЛЮЧИТЬ (Зеленый режим в трекере)
set_dmx_val(CH_DIMMER, 0)
set_dmx_val(CH_STROBE, 0)
dmx.render()
\# print(f"Target X:{int(x)} Y:{int(y)} | Pan:{pan} Tilt:{tilt} | Light: {'ON' if state else 'OFF'}")
else:
\# Если никого нет в кадре - ничего не делаем или выключаем свет
\# set_dmx_val(CH_DIMMER, 0)
\# dmx.render()
pass
except ConnectionRefusedError:
print("Не могу подключиться. stracker.py запущен? Повтор через 3 сек...")
time.sleep(3)
except Exception as e:
print(f"Ошибка в цикле: {e}")
time.sleep(1)
finally:
s.close()
if _name_ == "_main_":
main()
Подробнее здесь: https://stackoverflow.com/questions/798 ... controller
Программа Python, управляющая контроллером Open DMX ⇐ Python
Программы на Python
-
Anonymous
1767289297
Anonymous
I wrote a program that controls an OpenDMX controller (Enttec OpenDMX controller), but I'm getting an error.
an error appears when selecting a target
Ошибка в цикле: 'OpenDMXController' object has no attribute 'set_channel'
Please help
Code:
import socket
import json
import struct
import math
import time
from PyDMXControl.controllers import OpenDMXController
# ==========================================
# 1. НАСТРОЙКИ ПОДКЛЮЧЕНИЯ
# ==========================================
# Мы подключаемся к stracker.py, который работает на этом же компьютере
SERVER_IP = '127.0.0.1'
SERVER_PORT = 65432
# ==========================================
# 2. НАСТРОЙКИ СЦЕНЫ И КАМЕРЫ
# ==========================================
# Важно! Расстояние от проектора до сцены (в сантиметрах)
DISTANCE_TO_STAGE = 300.0
# Разрешение камеры (нужно для поиска центра кадра)
# Обычно Jetson использует 1280x720. Если у вас другое - поменяйте.
CAMERA_WIDTH = 1280
CAMERA_HEIGHT = 720
# ==========================================
# 3. НАСТРОЙКИ КАНАЛОВ (ПО ВАШЕМУ ФОТО)
# ==========================================
# Таблица из инструкции:
# 1: Pan (Горизонт)
# 2: Pan Fine (Тонкая) - пропускаем
# 3: Tilt (Вертикаль)
# 4: Tilt Fine (Тонкая) - пропускаем
# 5: Color (Цвет)
# 7: Strobe (Строб)
# 8: Dimmer (Яркость)
CH_PAN = 1
CH_TILT = 3
CH_COLOR = 5
CH_STROBE = 7
CH_DIMMER = 8
# Максимальные углы поворота головы (обычно 540 и 270)
MAX_PAN_ANGLE = 540.0
MAX_TILT_ANGLE = 270.0
# ==========================================
# 4. ИНИЦИАЛИЗАЦИЯ DMX
# ==========================================
print("--- ЗАПУСК DMX КЛИЕНТА ---")
print("Поиск контроллера OpenDMX...")
try:
\# Инициализация контроллера Enttec Open DMX
dmx = OpenDMXController()
print("\>\> Контроллер успешно подключен!")
кроме исключения как e:
print(f"\>\> ОШИБКА подключения контроллера: {e}")
print("Проверьте, подключен ли USB кабель и есть ли права (sudo).")
exit()
def set_dmx_val(канал, значение):
"""Безопасная отправка значения (0-255)"""
safe_val = max(0, min(255, int(value)))
dmx.set_channel(channel, safe_val)
# ==========================================
# 5. ФУНКЦИИ СЕТИ (Чтение протокола stracker.py)
# ==========================================
def recvall(sock, n):
"""Помощник: читать ровно n байт"""
data = bytearray()
while len(data) \< n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
def Recv_msg(sock):
"""Чтение сообщения с 4-байтовым заголовком длины (как в stracker.py)"""
\# 1. Читаем 4 байта (длина сообщения)
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
\# 2. Распаковываем длину (big-endian integer)
msglen = struct.unpack('\>I', raw_msglen)\[0\]
\# 3. Читаем само сообщение
return recvall(sock, msglen)
# =======================================
# 6. МАТЕМАТИКА (Координаты -> Углы)
# ========================================================(c>def Calculate_dmx_gls(cam_x, cam_y):\# 1. Находим отклонение от центра кадра в пикселях
\# Если cam_x = 640 (центр), то offset_x = 0
offset_x = cam_x - (CAMERA_WIDTH / 2)
\# Инверсия Y (часто камеры видят верх как 0, а проекторы низ как 0)
\# Если нужно инвертировать движение по вертикали, поменяйте знак
offset_y = cam_y - (CAMERA_HEIGHT / 2)
\# 2. Считаем угол через арктангенс
\# math.atan возвращает радианы, переводим в градусы
angle_x = math.degrees(math.atan(offset_x / DISTANCE_TO_STAGE))
angle_y = math.degrees(math.atan(offset_y / DISTANCE_TO_STAGE))
\# 3. Переводим угол в DMX (0-255)
\# 128 - это центр (0 градусов)
pan_dmx = 128 + (angle_x \* (255 / MAX_PAN_ANGLE))
tilt_dmx = 128 + (angle_y \* (255 / MAX_TILT_ANGLE))
return int(pan_dmx), int(tilt_dmx)
# ==========================================
# 7. ОСНОВНОЙ ЦИКЛ
# ==========================================
def main():
while True:
try:
print(f"Подключение к stracker.py ({SERVER_IP}:{SERVER_PORT})...")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, SERVER_PORT))
print("\>\> Соединение установлено! Ожидание данных...")
while True:
\# Получаем JSON от stracker.py
data_bytes = recv_msg(s)
if not data_bytes:
print("Сервер закрыл соединение.")
break
\# Декодируем
json_str = data_bytes.decode('utf-8')
targets = json.loads(json_str) # Это список \[...\]
\# Проверяем, есть ли кого отслеживать
\# stracker.py отправляет список, нам нужен тот, у кого 'State' или просто первый
if len(targets) \> 0:
\# Берем первую цель из списка (обычно это TargetID)
target = targets\[0\]
x = target.get('CenterX', 0)
y = target.get('CenterY', 0)
state = target.get('State', 0) # 1 - красный (вкл), 0 - зеленый (выкл)
\# --- 1. Движение ---
pan, tilt = calculate_dmx_angles(x, y)
set_dmx_val(CH_PAN, pan)
set_dmx_val(CH_TILT, tilt)
\# --- 2. Управление светом ---
\# На фото: Ch7 Strobe, Ch8 Dimmer.
\# Чтобы светило: Strobe=0 (без мигания), Dimmer=255.
\# Чтобы выключить: Dimmer=0.
if state == 1:
\# ВКЛЮЧИТЬ (Красный режим в трекере)
set_dmx_val(CH_COLOR, 0) # Белый цвет (0-139)
set_dmx_val(CH_STROBE, 0) # Строб открыт/выключен
set_dmx_val(CH_DIMMER, 255)# Яркость на полную
else:
\# ВЫКЛЮЧИТЬ (Зеленый режим в трекере)
set_dmx_val(CH_DIMMER, 0)
set_dmx_val(CH_STROBE, 0)
dmx.render()
\# print(f"Target X:{int(x)} Y:{int(y)} | Pan:{pan} Tilt:{tilt} | Light: {'ON' if state else 'OFF'}")
else:
\# Если никого нет в кадре - ничего не делаем или выключаем свет
\# set_dmx_val(CH_DIMMER, 0)
\# dmx.render()
pass
except ConnectionRefusedError:
print("Не могу подключиться. stracker.py запущен? Повтор через 3 сек...")
time.sleep(3)
except Exception as e:
print(f"Ошибка в цикле: {e}")
time.sleep(1)
finally:
s.close()
if _name_ == "_main_":
main()
Подробнее здесь: [url]https://stackoverflow.com/questions/79858713/python-program-that-controls-an-open-dmx-controller[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия