conv visualize

This commit is contained in:
Kseninia Mikhaylova 2024-12-12 11:50:09 +03:00
parent 886a9d0e5a
commit 31d1aff906
2 changed files with 138 additions and 94 deletions

119
robot/conveyor.py Normal file
View File

@ -0,0 +1,119 @@
import pybullet as p
import time
import threading
class ConveyorBelt:
def __init__(self, size, position, box_size, box_spacing, box_speed):
self.conveyor_size = size
self.conveyor_position = position
self.conveyor_id = self.create_conveyor(size, position)
self.box_size = box_size
self.box_spacing = box_spacing
self.box_speed = box_speed
self.boxes = []
self.create_boxes()
self.stop_thread = False
self.thread = threading.Thread(target=self.run)
self.thread.start()
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,
baseCollisionShapeIndex=collision_shape_id,
baseVisualShapeIndex=visual_shape_id,
basePosition=position,
)
return conveyor_id
def box_position(self, i=0):
x_position = (
self.conveyor_position[0]
- self.conveyor_size[0] * 0.5
+ i * (self.box_size[0] + self.box_spacing)
)
y_position = (
self.conveyor_position[1] + self.conveyor_size[1] * 0.5 - self.box_size[1]
)
z_position = (
self.conveyor_position[2] + self.conveyor_size[2] + self.box_size[2] * 0.5
)
return [x_position, y_position, z_position]
def create_boxes(self):
num_boxes = int(self.conveyor_size[0] / (self.box_size[0] + self.box_spacing))
for i in range(num_boxes):
position = self.box_position(i)
self.boxes.append(self.create_box(position))
def create_box(self, position):
collision_shape_id = p.createCollisionShape(
shapeType=p.GEOM_BOX,
halfExtents=[
self.box_size[0] / 2.0,
self.box_size[1] / 2.0,
self.box_size[2] / 2.0,
],
)
visual_shape_id = p.createVisualShape(
shapeType=p.GEOM_BOX,
halfExtents=[
self.box_size[0] / 2.0,
self.box_size[1] / 2.0,
self.box_size[2] / 2.0,
],
rgbaColor=[1, 0, 0, 1],
)
box_id = p.createMultiBody(
baseMass=1.0,
baseCollisionShapeIndex=collision_shape_id,
baseVisualShapeIndex=visual_shape_id,
basePosition=position,
baseOrientation=p.getQuaternionFromEuler([0, 0, 0]),
)
return box_id
def move_boxes(self):
# Двигаем коробки вдоль конвейера
for box_id in self.boxes[:]:
# Получаем текущую позицию коробки
pos, orn = p.getBasePositionAndOrientation(box_id)
# Проверяем, если коробка выходит за пределы конвейера по оси X
# Начальное положение коробки + её длина (по оси X)
if (
pos[0] + self.box_size[0] * 0.5
> self.conveyor_position[0] + self.conveyor_size[0] * 0.5
):
# Если коробка выходит за конец конвейера, она падает вниз (физика продолжает действовать)
# Удаляем коробку с конвейера
self.boxes.remove(box_id)
else:
# Двигаем коробку вдоль конвейера (по оси X)
new_pos = [pos[0] + self.box_speed, pos[1], pos[2]]
p.resetBasePositionAndOrientation(box_id, new_pos, orn)
# Добавляем новые коробки, если на конвейере меньше, чем максимально возможное количество
if len(self.boxes) < int(
self.conveyor_size[0] / (self.box_size[0] + self.box_spacing)
):
new_box = self.create_box(self.box_position())
self.boxes.append(new_box)
def run(self):
while not self.stop_thread:
self.move_boxes()
time.sleep(1)
def stop(self):
self.stop_thread = True
self.thread.join()

View File

@ -1,19 +1,13 @@
import socket
import json
import os import os
import math
import numpy as np import numpy as np
import time import time
from typing import Literal
from pprint import pprint
import threading
import pybullet as p import pybullet as p
import pybullet_industrial as pi
from logger import logger from logger import logger
from robot.conveyor import ConveyorBelt
class UrdfManager: class UrdfManager:
urdf_filename = None urdf_filename = None
@ -35,65 +29,21 @@ class UrdfManager:
self.physics_client = p.connect(getattr(p, type)) self.physics_client = p.connect(getattr(p, type))
logger.info(f"Connect to {self.physics_client} by {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): def load_models(self):
# p.loadURDF("urdf/plane.urdf", physicsClientId=self.physics_client) p.loadURDF(
os.path.join(self.application_path, "urdf", "plane.urdf"),
physicsClientId=self.physics_client,
)
urdf_path = os.path.join( urdf_path = os.path.join(
self.application_path, "urdf", f"{self.urdf_filename}.urdf" self.application_path, "urdf", f"{self.urdf_filename}.urdf"
) )
self.body_id = p.loadURDF( self.body_id = p.loadURDF(
urdf_path, self.robot_start_position, useFixedBase=True urdf_path,
self.robot_start_position,
useFixedBase=True
) )
p.setGravity(0, 0, -9.81, physicsClientId=self.physics_client)
def load_palletizing(self): def load_palletizing(self):
# Путь к URDF модели палеты # Путь к URDF модели палеты
@ -116,42 +66,17 @@ class UrdfManager:
/ 2.0, # Разместите палету выше, чтобы она не находилась на земле / 2.0, # Разместите палету выше, чтобы она не находилась на земле
] ]
pallet_orientation = p.getQuaternionFromEuler([0, 0, np.deg2rad(90)]) pallet_orientation = p.getQuaternionFromEuler([0, 0, np.deg2rad(90)])
self.pallet_id = p.loadURDF( # self.pallet_id = p.loadURDF(
urdf_path_pallet, pallet_position, pallet_orientation, useFixedBase=True # urdf_path_pallet, pallet_position, pallet_orientation, useFixedBase=True
) # )
# Создание коробок на палете conveyor_size = [3.0, 0.5, 0.1]
box_size = [0.2, 0.2, 0.2] # Размеры коробки: [ширина, высота, глубина] conveyor_position = [0.5, 1.5, 0.5]
boxes_per_row = 3 box_size = [0.2, 0.2, 0.2]
boxes_per_column = 2 box_spacing = 0.2
box_speed = 0.1 # Скорость движения коробок
for row in range(boxes_per_column): ConveyorBelt(conveyor_size, conveyor_position, box_size, box_spacing, box_speed)
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) time.sleep(1)