Python:如何中断,然后返回while循环,而不进行goto?

Python:如何中断,然后返回while循环,而不进行goto?,python,pid,goto,Python,Pid,Goto,我正在用python运行一个简单的PID控制程序。基本上是一个无限while循环,从传感器读取数据,然后计算相应的控制信号,并将诊断信息输出到终端 然而,有时在查看诊断信息时,我想通过中断循环、接受用户输入,然后返回到同一个循环来更改PID系数(本质上是循环使用的一些常量)。我想任意多次这样做 有了“goto”,这将是简单和容易的,正是我想要的。有人能给我一些python伪代码来做这件事吗?我真的想不出怎么做。我可以使用CTRL+C异常处理程序中断循环,但之后我无法返回主循环 一定有一些非常简单

我正在用python运行一个简单的PID控制程序。基本上是一个无限while循环,从传感器读取数据,然后计算相应的控制信号,并将诊断信息输出到终端

然而,有时在查看诊断信息时,我想通过中断循环、接受用户输入,然后返回到同一个循环来更改PID系数(本质上是循环使用的一些常量)。我想任意多次这样做

有了“goto”,这将是简单和容易的,正是我想要的。有人能给我一些python伪代码来做这件事吗?我真的想不出怎么做。我可以使用CTRL+C异常处理程序中断循环,但之后我无法返回主循环

一定有一些非常简单的方法可以做到这一点,但我想不出来。思想? 我的代码片段:

while True:
        t0 = get_temp_deg_c(thermocouple1)
        print "Hose Temperature = " + str(t0) + " deg C"

        t1 = get_temp_deg_c(thermocouple2)
        print "Valve Temperature = " + str(t1) + " deg C"

        # write temps to file
        fi.write(str(t0))
        fi.write(" " + str(t1) + "\n")

        error = setpoint - t0

        print "Setpoint = " + str(setpoint) + " deg C"
        print "Error = " + str(error) + " deg C"

        percent_error = error/setpoint*100
        print "Percent error = " + str(percent_error) + " %"

        duty_out = p.GenOut(percent_error)
        print "PID controller duty output: " + str(duty_out) + " %"
        # clamp the output
        if(duty_out) > 100:
            duty_out = 100
        if(duty_out < 0):
            duty_out = 0

        PWM.set_duty_cycle(PWM_pin, duty_out)

        # do we need to increment the setpoint?
        if( (setpoint - setpoint_precision) ... # omitted logic here

        # Here we return to the top

只要您同意在每次中断后从顶部重新启动,而不是在信号发出时返回到循环中的确切点,这是一个更难的问题:

while True:
    try:
        controller.main_loop()
    except KeyboardInterrupt:
        controller.set_coefficients()

如果您不想为IO使用单独的线程,可以使用生成器在键盘中断期间保持循环的状态

some_parameter = 1

def do_pid_stuff():
    while True:
        sensor_data1 = 'data'
        sensor_data2 = 'data'
        sensor_data3 = 'data'
        yield 'based on sensor_data1 ' * some_parameter
        yield 'based on sensor_data2 ' * some_parameter
        yield 'based on sensor_data3 ' * some_parameter


stuff = do_pid_stuff()
while True:
    try:
        for control_signal in stuff:
            print(control_signal)
    except KeyboardInterrupt:
        some_parameter = int(input())

因此,主循环将继续使用上一次执行的产出的新参数。然而,这需要重写您的循环。也许,它应该被分解成一个生成器,为您提供传感器数据,并分解成一个函数,该函数将根据传感器值实际执行操作。

您已经有了一些与循环交互的方法,我想指出另一种方法:选择。使用select,您可以等待任一用户输入。如果添加超时,那么如果没有可用的用户输入,就可以进入正常循环,并在那里与硬件交互

注:

这里是文档,但是在顶部考虑警告,而不是看模块。 此解决方案与使用键盘中断的解决方案类似,在参数更改时将停止与硬件交互。如果不能接受,则需要使用后台线程。 使用select更为普遍,您还可以等待网络流量。 您的硬件不会尽可能频繁地进行维修,但在维修之间会有一个固定的暂停。从好的方面来说,你也不会使用一个完整的CPU。
您是否可以修改代码以在线程中运行主循环?也许在while循环中执行线程可以完成这项工作,但我不确定线程是否允许外部线程引用。您能给我们一个实际的代码示例吗?您可以在交互式shell中构建这样的程序,当pid循环在线程中运行时,用户可以在程序中戳变量,基本上看起来您想要轮询键盘的输入缓冲区?这个答案提到了一些方法。大家好,添加了一个包含要点的代码段。