added collision protection
This commit is contained in:
parent
da78207b9b
commit
8d75f952e4
@ -251,6 +251,74 @@ def project_to_conveyor(info, yaw, csv_x, csv_z):
|
|||||||
t = vx * fx + vz * fz
|
t = vx * fx + vz * fz
|
||||||
return cx + fx * t, cz + fz * t
|
return cx + fx * t, cz + fz * t
|
||||||
|
|
||||||
|
# -----------------------
|
||||||
|
# PARSE EXISTING BUTTONS FROM SCENE
|
||||||
|
# -----------------------
|
||||||
|
existing_buttons = []
|
||||||
|
|
||||||
|
in_button_node = False
|
||||||
|
current_button_name = None
|
||||||
|
current_button_transform = None
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
# Detect button nodes
|
||||||
|
if f'instance=ExtResource("{BUTTON_RES_ID}")' in line:
|
||||||
|
in_button_node = True
|
||||||
|
m = re.search(r'name="([^"]+)"', line)
|
||||||
|
if m:
|
||||||
|
current_button_name = m.group(1)
|
||||||
|
|
||||||
|
# Extract transform if we're in a button node
|
||||||
|
if in_button_node and line.strip().startswith("transform = Transform3D"):
|
||||||
|
vals = [float(v) for v in re.search(r"\(([^)]+)\)", line).group(1).split(",")]
|
||||||
|
current_button_transform = (vals[9], vals[11]) # x, z position
|
||||||
|
|
||||||
|
if current_button_name and current_button_transform:
|
||||||
|
existing_buttons.append({
|
||||||
|
'name': current_button_name,
|
||||||
|
'x': current_button_transform[0],
|
||||||
|
'z': current_button_transform[1]
|
||||||
|
})
|
||||||
|
|
||||||
|
in_button_node = False
|
||||||
|
current_button_name = None
|
||||||
|
current_button_transform = None
|
||||||
|
|
||||||
|
print(f"\n📍 Found {len(existing_buttons)} existing buttons in scene")
|
||||||
|
|
||||||
|
# -----------------------
|
||||||
|
# COLLISION DETECTION HELPER
|
||||||
|
# -----------------------
|
||||||
|
MIN_BUTTON_SPACING = 0.5 # minimum distance between buttons (meters)
|
||||||
|
|
||||||
|
def check_collision_and_adjust(x, z, yaw, existing_buttons):
|
||||||
|
"""
|
||||||
|
Check if position (x, z) collides with existing buttons.
|
||||||
|
If collision detected, shift along conveyor direction (yaw).
|
||||||
|
Returns adjusted (x, z) position.
|
||||||
|
"""
|
||||||
|
max_attempts = 20
|
||||||
|
shift_distance = 0.3 # how much to shift each attempt
|
||||||
|
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
collision = False
|
||||||
|
|
||||||
|
for btn in existing_buttons:
|
||||||
|
dist = math.sqrt((x - btn['x'])**2 + (z - btn['z'])**2)
|
||||||
|
if dist < MIN_BUTTON_SPACING:
|
||||||
|
collision = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not collision:
|
||||||
|
return x, z
|
||||||
|
|
||||||
|
# Shift forward along conveyor
|
||||||
|
x += math.cos(yaw) * shift_distance
|
||||||
|
z += math.sin(yaw) * shift_distance
|
||||||
|
|
||||||
|
print(f"⚠ Warning: Could not find collision-free position after {max_attempts} attempts")
|
||||||
|
return x, z
|
||||||
|
|
||||||
# -----------------------
|
# -----------------------
|
||||||
# APPEND DEVICES
|
# APPEND DEVICES
|
||||||
# -----------------------
|
# -----------------------
|
||||||
@ -381,6 +449,9 @@ if place_buttons:
|
|||||||
else:
|
else:
|
||||||
btn_yaw = yaw
|
btn_yaw = yaw
|
||||||
|
|
||||||
|
# Check for collisions with existing buttons
|
||||||
|
x, z = check_collision_and_adjust(x, z, yaw, existing_buttons)
|
||||||
|
|
||||||
c, s = math.cos(btn_yaw), math.sin(btn_yaw)
|
c, s = math.cos(btn_yaw), math.sin(btn_yaw)
|
||||||
|
|
||||||
transform = (
|
transform = (
|
||||||
@ -398,6 +469,9 @@ if place_buttons:
|
|||||||
f'lamp_tag_name = "{name}_LT_OIP"\n'
|
f'lamp_tag_name = "{name}_LT_OIP"\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add to existing buttons list to prevent overlap with other new buttons
|
||||||
|
existing_buttons.append({'name': name, 'x': x, 'z': z})
|
||||||
|
|
||||||
# -------- SS STATIONS --------
|
# -------- SS STATIONS --------
|
||||||
if place_ss:
|
if place_ss:
|
||||||
for key in sorted(ss_by_conveyor.keys()):
|
for key in sorted(ss_by_conveyor.keys()):
|
||||||
@ -480,6 +554,9 @@ if place_ss:
|
|||||||
fz = math.sin(yaw)
|
fz = math.sin(yaw)
|
||||||
STATION_SPREAD = 0.45
|
STATION_SPREAD = 0.45
|
||||||
|
|
||||||
|
# Check for collisions with existing buttons
|
||||||
|
x, z = check_collision_and_adjust(x, z, yaw, existing_buttons)
|
||||||
|
|
||||||
# -------- START (SPB) --------
|
# -------- START (SPB) --------
|
||||||
start_node = f"{station}_SPB"
|
start_node = f"{station}_SPB"
|
||||||
start_x = x + fx * (STATION_SPREAD / 2)
|
start_x = x + fx * (STATION_SPREAD / 2)
|
||||||
@ -501,6 +578,9 @@ if place_ss:
|
|||||||
f'lamp_tag_name = "{station}_SPB_LT_OIP"\n'
|
f'lamp_tag_name = "{station}_SPB_LT_OIP"\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add to existing buttons list
|
||||||
|
existing_buttons.append({'name': start_node, 'x': start_x, 'z': start_z})
|
||||||
|
|
||||||
# -------- STOP (STPB) --------
|
# -------- STOP (STPB) --------
|
||||||
stop_node = f"{station}_STPB"
|
stop_node = f"{station}_STPB"
|
||||||
stop_x = x - fx * (STATION_SPREAD / 2)
|
stop_x = x - fx * (STATION_SPREAD / 2)
|
||||||
@ -521,6 +601,9 @@ if place_ss:
|
|||||||
f'pushbutton_tag_name = "{station}_STPB_OIP"\n'
|
f'pushbutton_tag_name = "{station}_STPB_OIP"\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add to existing buttons list
|
||||||
|
existing_buttons.append({'name': stop_node, 'x': stop_x, 'z': stop_z})
|
||||||
|
|
||||||
# -------- EPC DEVICES --------
|
# -------- EPC DEVICES --------
|
||||||
if place_epc:
|
if place_epc:
|
||||||
for key in sorted(epc_by_conveyor.keys()):
|
for key in sorted(epc_by_conveyor.keys()):
|
||||||
@ -566,6 +649,9 @@ if place_epc:
|
|||||||
fx = math.cos(yaw)
|
fx = math.cos(yaw)
|
||||||
fz = math.sin(yaw)
|
fz = math.sin(yaw)
|
||||||
|
|
||||||
|
# Check for collisions with existing buttons
|
||||||
|
x, z = check_collision_and_adjust(x, z, yaw, existing_buttons)
|
||||||
|
|
||||||
c, s = math.cos(base_yaw), math.sin(base_yaw)
|
c, s = math.cos(base_yaw), math.sin(base_yaw)
|
||||||
|
|
||||||
# -------- CH1 --------
|
# -------- CH1 --------
|
||||||
@ -588,6 +674,9 @@ if place_epc:
|
|||||||
f'pushbutton_tag_name = "{name}_CH1_OIP"\n'
|
f'pushbutton_tag_name = "{name}_CH1_OIP"\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add to existing buttons list
|
||||||
|
existing_buttons.append({'name': ch1_name, 'x': ch1_x, 'z': ch1_z})
|
||||||
|
|
||||||
# -------- CH2 --------
|
# -------- CH2 --------
|
||||||
ch2_name = f"{name}_CH2"
|
ch2_name = f"{name}_CH2"
|
||||||
ch2_x = x - fx * (EPC_SPREAD / 2)
|
ch2_x = x - fx * (EPC_SPREAD / 2)
|
||||||
@ -608,6 +697,9 @@ if place_epc:
|
|||||||
f'pushbutton_tag_name = "{name}_CH2_OIP"\n'
|
f'pushbutton_tag_name = "{name}_CH2_OIP"\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add to existing buttons list
|
||||||
|
existing_buttons.append({'name': ch2_name, 'x': ch2_x, 'z': ch2_z})
|
||||||
|
|
||||||
|
|
||||||
scene_text += "".join(node_blocks)
|
scene_text += "".join(node_blocks)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user