Python机械臂航点编辑器运行后清空TXT文件,求故障排查
机械臂航点编辑器TXT文件莫名清空问题排查与修复
问题概述
运行程序后所有TXT文件数据被清空,原因不明。
详细描述
为机械臂开发航点编辑器/保存器,程序支持选择对应TXT文件(航点集)修改或新增航点。首次运行时可正常输入、修改并保存,新增航点旧数据留存,关闭后TXT文件完整。但重启程序时,即便未完成第一个输入选择(尚未指定编辑的TXT文件)就立即终止,所有TXT文件都会被清空。已排查导入模块(旧版控制系统无此问题),耗时2天仍无进展。
原代码
from machine import Pin, PWM, ADC, I2C from time import sleep import Move from pico_i2c_lcd import I2cLcd def EDITMODE(): analog_value = machine.ADC(28) i2c = I2C(0, sda=Pin(0), scl =Pin(1), freq=400000) I2C_ADDR = i2c.scan()[0] lcd = I2cLcd(i2c, I2C_ADDR, 2, 16) stv=0 base = PWM(Pin(18)) base.freq(50) lcdt = 1 j2 = PWM(Pin(19)) j2.freq(50) j3 = PWM(Pin(20)) j3.freq(50) claw = PWM(Pin(21)) claw.freq(50) buttonmove = 20000 b1 = Pin(2, Pin.IN, Pin.PULL_DOWN) b2 = Pin(3, Pin.IN, Pin.PULL_DOWN) b3= Pin(4, Pin.IN, Pin.PULL_DOWN) b4= Pin(5, Pin.IN, Pin.PULL_DOWN) b5= Pin(6, Pin.IN, Pin.PULL_DOWN) b6= Pin(7, Pin.IN, Pin.PULL_DOWN) b7= Pin(8, Pin.IN, Pin.PULL_DOWN) b8= Pin(9, Pin.IN, Pin.PULL_DOWN) b9= Pin(10, Pin.IN, Pin.PULL_DOWN) b10= Pin(11, Pin.IN, Pin.PULL_DOWN) b11= Pin(12, Pin.IN, Pin.PULL_DOWN) b12= Pin(13, Pin.IN, Pin.PULL_DOWN) bshift= Pin(14, Pin.IN, Pin.PULL_DOWN) l1led = Pin(16, Pin.OUT) l2led= Pin(17, Pin.OUT) global gha gha = 0 buttonmove = 5000 j1v =1222500 j4v =1282500 j2v =1312500 j3v=1762500 break1 = 0 while True: if break1 ==1: break #decides which waypoint to edit eprog = int(input('Which Set would you like to edit (1-5) ')) if eprog == 1: curentprogram = 'Prog1.txt' elif eprog == 2: curentprogram = 'Prog2.txt' elif eprog == 3: curentprogram = 'Prog3.txt' elif eprog == 4: curentprogram = 'Prog4.txt' elif eprog == 5: curentprogram = 'Prog5.txt' file = open(curentprogram, "r") WPL = file.readlines() file.close() x = len(WPL) print(WPL) print('There are ', str(x/6), ' Waypoints currently set') epoint1 = int(input('Which waypoint would you like to set? ')) epoint = (epoint1*6) if epoint >0: epoint = epoint+1 print('Move robot to desired position then save waypoint') sleepvalue = 0 while True: b1v = b1.value() b2v = b2.value() b3v = b3.value() b4v = b4.value() b5v = b5.value() b6v = b6.value() b7v = b12.value() b8v = b11.value() b9v = b10.value() b10v = b9.value() b11v = b8.value() b12v = b7.value() shiftb = bshift.value() if shiftb == 1: l2led(0) if b1v ==1: j1v = j1v+buttonmove if b12v ==1: j1v = j1v-buttonmove if b2v ==1: j2v = j2v+buttonmove if b11v ==1: j2v = j2v-buttonmove if b3v ==1: j4v = j4v - buttonmove if b10v ==1: j4v = j4v + buttonmove if b4v ==1: j3v = j3v+buttonmove if b9v ==1: j3v = j3v-buttonmove else: l2led(1) if b6v == 1: sleepvalue = sleepvalue+1 print('sleep time =', sleepvalue) sleep(.5) if b7v == 1: sleepvalue = sleepvalue-1 if sleepvalue < 0: sleepvalue = 0 print('sleep time =', sleepvalue) sleep(.5) if b1v == 1: print(epoint, x) if epoint+.01 > (x/6): print('value not written, new waypoint value = ', str((x/6)+1)) WPL.append(j1v) WPL.append(j2v) WPL.append(j3v) WPL.append(j4v) WPL.append(x/6) WPL.append(sleepvalue) else: print('Saving Point') print(epoint) epoint = int(epoint) WPL[epoint] = j1v WPL[epoint+1] = j2v WPL[epoint+2] = j3v WPL[epoint+3] = j4v WPL[epoint+4] = (epoint/6) WPL[epoint+5] = sleepvalue print(WPL) file = open(curentprogram, 'w') file.write('') file.close file = open(curentprogram, 'a') print(WPL) for item in WPL: print(item, 'bannana') file.write((str(item))+'\n') file.close() restart = input('would you like to set another point? (y/n) ') if restart == 'n' or restart == 'N': return else: break sleep(.025) print(j1v, j2v, j3v, j4v) #base.duty_ns(int(j1v)) #j2.duty_ns(int(j2v)) #j3.duty_ns(int(j3v)) #claw.duty_ns(int(j4v)) if __name__ == '__main__': print('hello') EDITMODE()
问题诊断
- 导入模块的隐藏操作:核心问题大概率出在
import Move模块中——如果Move.py存在模块级别的文件操作(不在函数内,导入时自动执行),比如遍历Prog1-Prog5.txt并以'w'模式打开,会直接清空所有文件,且这个操作在程序启动时就会触发,和主逻辑是否执行无关。 - 输入阶段的异常未处理:用户在输入
eprog时终止程序(如Ctrl+C),会抛出KeyboardInterrupt,若导入模块的异常处理逻辑中包含文件操作,也可能触发清空。 - 文件操作的低级错误:原代码中
file.close少了括号,导致文件未正确关闭,可能引发后续不可预测的文件状态问题。
修复步骤
步骤1:检查并修复Move.py模块
打开Move.py,确认是否存在以下代码:
- 模块顶层(不在函数内)的文件遍历/清空逻辑
- 启动时自动执行的
Prog*.txt写入操作
如果存在,将这些代码移到函数内部,仅在需要时主动调用,避免导入时自动执行。
步骤2:添加输入容错与异常捕获
修改主程序的输入逻辑,避免未赋值变量和异常导致的意外行为:
while True: if break1 == 1: break # 处理输入异常和范围校验 try: eprog = int(input('Which Set would you like to edit (1-5) ')) if eprog not in range(1,6): print("请输入1-5之间的数字") continue except ValueError: print("输入无效,请输入数字") continue except KeyboardInterrupt: print("\n程序终止") return # 直接退出,避免后续代码执行 # 赋值文件名 curentprogram = f'Prog{eprog}.txt' # 后续文件操作...
步骤3:优化文件写入逻辑
替换原有的清空+追加操作,使用with语句确保文件正确关闭,同时简化流程:
# 替换原保存代码 with open(curentprogram, 'w') as file: for item in WPL: file.write(f"{item}\n")
步骤4:全局异常捕获
在主入口添加异常处理,防止意外终止时触发未知操作:
if __name__ == '__main__': print('hello') try: EDITMODE() except KeyboardInterrupt: print("\n程序正常终止") except Exception as e: print(f"程序出错:{e}")
额外优化建议
- 所有文件操作统一使用
with语句,避免资源泄漏和未关闭文件的问题 - 对
curentprogram变量初始化(如设为None),使用前做非空校验 - 每次保存航点前,自动复制原文件作为备份,防止数据丢失
内容的提问来源于stack exchange,提问作者Atticus Atwood
相关产品推荐
相关产品推荐

