You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

问题诊断

  1. 导入模块的隐藏操作:核心问题大概率出在import Move模块中——如果Move.py存在模块级别的文件操作(不在函数内,导入时自动执行),比如遍历Prog1-Prog5.txt并以'w'模式打开,会直接清空所有文件,且这个操作在程序启动时就会触发,和主逻辑是否执行无关。
  2. 输入阶段的异常未处理:用户在输入eprog时终止程序(如Ctrl+C),会抛出KeyboardInterrupt,若导入模块的异常处理逻辑中包含文件操作,也可能触发清空。
  3. 文件操作的低级错误:原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:45:38