194 lines
7.4 KiB
Python
194 lines
7.4 KiB
Python
|
|
# main.py
|
|||
|
|
import time
|
|||
|
|
from config.settings import app_set_config
|
|||
|
|
from core.system import FeedingControlSystem
|
|||
|
|
from hardware import relay
|
|||
|
|
from hardware.relay import RelayController
|
|||
|
|
import threading
|
|||
|
|
import time
|
|||
|
|
import cv2
|
|||
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
import io
|
|||
|
|
|
|||
|
|
|
|||
|
|
class OutputRedirector(io.StringIO):
|
|||
|
|
"""
|
|||
|
|
自定义输出重定向器,用于处理所有线程的输出
|
|||
|
|
确保输入提示能在其他线程输出后重新显示,且保留用户当前输入
|
|||
|
|
"""
|
|||
|
|
def __init__(self, original_stdout):
|
|||
|
|
super().__init__()
|
|||
|
|
self.original_stdout = original_stdout
|
|||
|
|
self.input_prompt = "请输入新值:"
|
|||
|
|
self.input_thread_active = False
|
|||
|
|
self.current_input = "" # 跟踪用户当前输入
|
|||
|
|
self.lock = threading.Lock()
|
|||
|
|
|
|||
|
|
def write(self, text):
|
|||
|
|
with self.lock:
|
|||
|
|
# 写入原始输出
|
|||
|
|
self.original_stdout.write(text)
|
|||
|
|
self.original_stdout.flush()
|
|||
|
|
|
|||
|
|
# 如果输入线程活跃,并且输出是换行符,重新显示输入提示和当前输入
|
|||
|
|
if self.input_thread_active and '\n' in text:
|
|||
|
|
# 清除当前行并重新显示输入提示和用户当前输入
|
|||
|
|
self.original_stdout.write("\r" + " " * 100 + "\r")
|
|||
|
|
self.original_stdout.write(f"{self.input_prompt}{self.current_input}")
|
|||
|
|
self.original_stdout.flush()
|
|||
|
|
|
|||
|
|
def flush(self):
|
|||
|
|
with self.lock:
|
|||
|
|
self.original_stdout.flush()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
# 加载配置
|
|||
|
|
# 初始化系统
|
|||
|
|
|
|||
|
|
|
|||
|
|
# replay_controller.control(replay_controller.DOOR_LOWER_OPEN, 'open')
|
|||
|
|
# time.sleep(1)
|
|||
|
|
# replay_controller.control(replay_controller.DOOR_LOWER_OPEN, 'close')
|
|||
|
|
# replay_controller.control(replay_controller.DOOR_LOWER_CLOSE, 'close')
|
|||
|
|
|
|||
|
|
# replay_controller.control_upper_open()
|
|||
|
|
|
|||
|
|
# replay_controller.control(replay_controller.DOOR_LOWER_OPEN, 'open')
|
|||
|
|
# time.sleep(5)
|
|||
|
|
# replay_controller.control(replay_controller.DOOR_LOWER_OPEN, 'close')
|
|||
|
|
|
|||
|
|
# image=cv2.imread(os.path.join(app_set_config.project_root,'test.jpeg'))
|
|||
|
|
# image=cv2.flip(image, 0)
|
|||
|
|
# cv2.imshow('test',image)
|
|||
|
|
# cv2.waitKey(1)
|
|||
|
|
|
|||
|
|
# replay_controller.control(system.relay_controller.DOOR_LOWER_OPEN, 'open')
|
|||
|
|
|
|||
|
|
system = FeedingControlSystem()
|
|||
|
|
# system.vision_detector.detect_angle()
|
|||
|
|
# while True:
|
|||
|
|
# system.feeding_controller.pulse_control_door_for_maintaining()
|
|||
|
|
# time.sleep(5)
|
|||
|
|
|
|||
|
|
# 初始设置
|
|||
|
|
system.state.vehicle_aligned=True
|
|||
|
|
#假设在 fertilize room
|
|||
|
|
system.state._upper_door_position='over_lower'
|
|||
|
|
|
|||
|
|
# 创建输出重定向器
|
|||
|
|
original_stdout = sys.stdout
|
|||
|
|
output_redirector = OutputRedirector(original_stdout)
|
|||
|
|
sys.stdout = output_redirector
|
|||
|
|
|
|||
|
|
# 创建输入线程函数
|
|||
|
|
def input_thread():
|
|||
|
|
import sys
|
|||
|
|
import threading
|
|||
|
|
|
|||
|
|
# 初始提示只显示一次
|
|||
|
|
initial_prompt = """
|
|||
|
|
输入线程启动提示
|
|||
|
|
--------------------------
|
|||
|
|
可以随时输入新值来更新系统状态
|
|||
|
|
格式:需求重量,完成重量,溢出状态
|
|||
|
|
例如:500,300,大堆料 或 500,300,小堆料 或 500,300,未堆料
|
|||
|
|
输入'q'退出程序
|
|||
|
|
--------------------------
|
|||
|
|
"""
|
|||
|
|
print(initial_prompt)
|
|||
|
|
|
|||
|
|
# 标记输入线程为活跃状态
|
|||
|
|
output_redirector.input_thread_active = True
|
|||
|
|
|
|||
|
|
while True:
|
|||
|
|
try:
|
|||
|
|
import termios
|
|||
|
|
import tty
|
|||
|
|
|
|||
|
|
# 获取当前终端设置
|
|||
|
|
old_settings = termios.tcgetattr(sys.stdin)
|
|||
|
|
try:
|
|||
|
|
tty.setcbreak(sys.stdin.fileno()) # 设置为cbreak模式,允许逐字符读取
|
|||
|
|
|
|||
|
|
# 显示初始提示和当前输入
|
|||
|
|
sys.stdout.write("\r" + " " * 100 + "\r")
|
|||
|
|
sys.stdout.write(f"{output_redirector.input_prompt}{output_redirector.current_input}")
|
|||
|
|
sys.stdout.flush()
|
|||
|
|
|
|||
|
|
while True:
|
|||
|
|
char = sys.stdin.read(1) # 读取一个字符
|
|||
|
|
|
|||
|
|
if char == '\x03': # Ctrl+C
|
|||
|
|
raise KeyboardInterrupt
|
|||
|
|
elif char in ['\r', '\n']: # 回车键
|
|||
|
|
sys.stdout.write("\n")
|
|||
|
|
sys.stdout.flush()
|
|||
|
|
break
|
|||
|
|
elif char == '\x7f': # 退格键
|
|||
|
|
if len(output_redirector.current_input) > 0:
|
|||
|
|
output_redirector.current_input = output_redirector.current_input[:-1]
|
|||
|
|
# 从显示中删除最后一个字符
|
|||
|
|
sys.stdout.write("\b \b")
|
|||
|
|
sys.stdout.flush()
|
|||
|
|
else:
|
|||
|
|
output_redirector.current_input += char
|
|||
|
|
sys.stdout.write(char)
|
|||
|
|
sys.stdout.flush()
|
|||
|
|
finally:
|
|||
|
|
# 恢复终端设置
|
|||
|
|
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
|
|||
|
|
|
|||
|
|
# 获取最终输入并重置当前输入
|
|||
|
|
user_input = output_redirector.current_input
|
|||
|
|
output_redirector.current_input = "" # 重置为下一次输入准备
|
|||
|
|
|
|||
|
|
if user_input.lower() == 'q':
|
|||
|
|
print("\n收到退出信号,正在关闭系统...")
|
|||
|
|
output_redirector.input_thread_active = False
|
|||
|
|
system.stop()
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
# 分割输入值,处理不同参数数量
|
|||
|
|
input_parts = [part.strip() for part in user_input.split(',')]
|
|||
|
|
if len(input_parts) >= 2:
|
|||
|
|
# 更新基本参数
|
|||
|
|
system.state._mould_need_weight = float(input_parts[0])
|
|||
|
|
system.state._mould_finish_weight = float(input_parts[1])
|
|||
|
|
|
|||
|
|
if system.state._mould_finish_weight>400:
|
|||
|
|
system.state.overflow_detected='大堆料'
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 输出更新结果,使用换行符分隔
|
|||
|
|
update_msg = f"\n已更新:\n 需求重量 = {system.state._mould_need_weight} kg\n 完成重量 = {system.state._mould_finish_weight} kg"
|
|||
|
|
print(f"溢出状态 = {system.state.overflow_detected}")
|
|||
|
|
print(update_msg)
|
|||
|
|
else:
|
|||
|
|
print("\n输入格式错误:至少需要输入需求重量和完成重量")
|
|||
|
|
|
|||
|
|
except ValueError as e:
|
|||
|
|
print(f"\n输入格式错误,请重新输入。错误信息:{e}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"\n发生错误:{e}")
|
|||
|
|
output_redirector.input_thread_active = False
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
# 启动输入线程
|
|||
|
|
input_thread = threading.Thread(target=input_thread, daemon=True)
|
|||
|
|
input_thread.start()
|
|||
|
|
system.relay_controller.control(system.relay_controller.DOOR_LOWER_OPEN, 'open')
|
|||
|
|
# 启动视觉控制
|
|||
|
|
system.camera_controller.start_cameras()
|
|||
|
|
system.start_visual_control()
|
|||
|
|
|
|||
|
|
# 主线程保持运行
|
|||
|
|
while True:
|
|||
|
|
# print(f'当前重量22:{system.state._mould_finish_weight:.2f}kg, 目标重量:{system.state._mould_need_weight:.2f}kg')
|
|||
|
|
time.sleep(1)
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|