163 lines
6.5 KiB
Python
163 lines
6.5 KiB
Python
import socket
|
||
import json
|
||
import os
|
||
import math
|
||
import numpy as np
|
||
import time
|
||
|
||
from typing import Literal
|
||
from pprint import pprint
|
||
|
||
import threading
|
||
import pybullet as p
|
||
import pybullet_industrial as pi
|
||
|
||
from logger import logger
|
||
|
||
|
||
class UrdfManager:
|
||
urdf_filename = None
|
||
urdf_filename_tool = "welding_gun"
|
||
physics_client = None
|
||
body_id = None
|
||
|
||
def __init__(self, robot_start_position, application_path):
|
||
self.robot_start_position = robot_start_position
|
||
self.application_path = application_path
|
||
|
||
def start_loop(self, urdf):
|
||
self.urdf_filename = urdf
|
||
|
||
p.resetSimulation()
|
||
self.load_models()
|
||
|
||
def run_pybullet(self, type="DIRECT"):
|
||
self.physics_client = p.connect(getattr(p, type))
|
||
logger.info(f"Connect to {self.physics_client} by {type}")
|
||
|
||
def create_cube(self, size, position):
|
||
# Создание формы коллизии для куба
|
||
collision_shape_id = p.createCollisionShape(
|
||
shapeType=p.GEOM_BOX,
|
||
halfExtents=[size[0] / 2.0, size[1] / 2.0, size[2] / 2.0] # halfExtents задаются радиусами по осям x, y и z
|
||
)
|
||
|
||
# Создание визуальной формы для куба
|
||
visual_shape_id = p.createVisualShape(
|
||
shapeType=p.GEOM_BOX,
|
||
halfExtents=[size[0] / 2.0, size[1] / 2.0, size[2] / 2.0],
|
||
rgbaColor=[0, 0, 1, 1] # Синий цвет
|
||
)
|
||
|
||
# Создание многосоставного тела с формой коллизии и визуальной формой
|
||
body_id = p.createMultiBody(
|
||
baseMass=1.0, # Масса тела
|
||
baseCollisionShapeIndex=collision_shape_id,
|
||
baseVisualShapeIndex=visual_shape_id,
|
||
basePosition=position
|
||
)
|
||
|
||
return body_id
|
||
|
||
def create_conveyor(self, size, position):
|
||
collision_shape_id = p.createCollisionShape(
|
||
shapeType=p.GEOM_BOX,
|
||
halfExtents=[size[0] / 2.0, size[1] / 2.0, size[2] / 2.0]
|
||
)
|
||
# Создание визуальной формы для конвейера
|
||
visual_shape_id = p.createVisualShape(
|
||
shapeType=p.GEOM_BOX,
|
||
halfExtents=[size[0] / 2.0, size[1] / 2.0, size[2] / 2.0],
|
||
rgbaColor=[0.5, 0.5, 0.5, 1] # Серый цвет для конвейера
|
||
)
|
||
|
||
# Создание тела для конвейера (можно без массы, если оно не должно взаимодействовать с другими объектами)
|
||
conveyor_id = p.createMultiBody(
|
||
baseMass=0.0, # Это статичный объект, поэтому масса 0
|
||
baseCollisionShapeIndex=collision_shape_id,
|
||
baseVisualShapeIndex=visual_shape_id,
|
||
basePosition=position
|
||
)
|
||
|
||
return conveyor_id
|
||
|
||
def load_models(self):
|
||
# p.loadURDF("urdf/plane.urdf", physicsClientId=self.physics_client)
|
||
|
||
urdf_path = os.path.join(
|
||
self.application_path, "urdf", f"{self.urdf_filename}.urdf"
|
||
)
|
||
self.body_id = p.loadURDF(
|
||
urdf_path, self.robot_start_position, useFixedBase=True
|
||
)
|
||
|
||
# Путь к URDF модели палеты
|
||
urdf_path_pallet = os.path.join(
|
||
self.application_path, "urdf", "europallet.urdf" # Убедитесь, что имя файла соответствует
|
||
)
|
||
|
||
# Загрузка палеты рядом с роботом
|
||
# Предположим, что вы хотите расположить палету на расстоянии от робота
|
||
pallet_offset_x = 1.5 # Расстояние в метрах по оси X
|
||
pallet_offset_y = 0.0 # Расстояние по оси Y
|
||
pallet_height = 0.145 # Высота палеты (подгонка под высоту робота)
|
||
|
||
pallet_position = [
|
||
self.robot_start_position[0] + pallet_offset_x,
|
||
self.robot_start_position[1] + pallet_offset_y,
|
||
pallet_height / 2.0 # Разместите палету выше, чтобы она не находилась на земле
|
||
]
|
||
pallet_orientation = p.getQuaternionFromEuler([0, 0, np.deg2rad(90)])
|
||
self.pallet_id = p.loadURDF(
|
||
urdf_path_pallet, pallet_position, pallet_orientation, useFixedBase=True
|
||
)
|
||
|
||
# Создание коробок на палете
|
||
box_size = [0.2, 0.2, 0.2] # Размеры коробки: [ширина, высота, глубина]
|
||
boxes_per_row = 3
|
||
boxes_per_column = 2
|
||
|
||
for row in range(boxes_per_column):
|
||
for col in range(boxes_per_row):
|
||
box_x_offset = col * (box_size[0] + 0.05)
|
||
box_y_offset = row * (box_size[1] + 0.05)
|
||
box_z_position = pallet_height + (box_size[2] / 2)
|
||
|
||
box_position = [
|
||
pallet_position[0] + box_x_offset - (boxes_per_row * (box_size[0] + 0.05) / 2),
|
||
pallet_position[1] + box_y_offset - (boxes_per_column * (box_size[1] + 0.05) / 2),
|
||
box_z_position
|
||
]
|
||
|
||
# Создаем кубик
|
||
self.create_cube(box_size, box_position)
|
||
|
||
# Создание конвейера
|
||
conveyor_size = [3.0, 0.5, 0.1] # Длина, ширина и высота
|
||
conveyor_position = [0.5, 1.5, 0.5] # Позиция в пространстве (выше уровня земли)
|
||
self.conveyor_id = self.create_conveyor(conveyor_size, conveyor_position)
|
||
|
||
time.sleep(1)
|
||
|
||
def get_pybullet_image(self):
|
||
if self.physics_client is None:
|
||
return
|
||
|
||
width, height, rgb, _, _ = p.getCameraImage(
|
||
width=500,
|
||
height=500,
|
||
viewMatrix=p.computeViewMatrix(
|
||
cameraEyePosition=[4, -4, 1.5],
|
||
# cameraEyePosition=[4,-4,4],
|
||
cameraTargetPosition=[0, 0, 0], # Центр фокусировки камеры
|
||
cameraUpVector=[0, 0, 1], # Направление вверх
|
||
),
|
||
projectionMatrix=p.computeProjectionMatrixFOV(
|
||
fov=60.0, aspect=1.0, nearVal=0.1, farVal=10.0
|
||
),
|
||
# renderer=p.ER_TINY_RENDERER,
|
||
physicsClientId=self.physics_client,
|
||
)
|
||
|
||
return (rgb, width, height)
|