2011-02-22 104 views
0

我有一个伺服控制器,它将一个物体越来越靠近传感器,试图触发它。我怎样才能让这个程序更优雅?

我想要的距离为开始在15.5。但是,在每次迭代中,我都希望它减小距离.1,直到传感器触发。为了方便起见,我想退出while循环,将变量$ currentHeight设置为该触发高度,所以我将减量线放在循环的标点处。

但是,我必须在while循环之前硬编码一个15.6的起始点,以便它在循环的第一行中递减到15.5。

这看起来并不高雅。有关如何改变这种情况的任何建议?顺便说一句,这是Tcl为你所有的老学校和晦涩难懂的程序员。 ;)

代码:

set currrentDistance 15.6 
set sensorStatus 4 

while {$sensorStatus == 1)} { 
    set currentDistance [expr $currentDistance - .1] 
    moveServo $currentHeight 
    set sensorStatus [watchSensor 2] 
} 
+1

这将永远不会进入循环,因为sensorStatus!= 1开始 – 2011-02-23 00:34:12

+0

@glenn:除非它是链接到某些内存映射硬件的变量,或者它具有设置的跟踪。那会很丑。 – 2011-02-23 08:49:29

+0

我不得不改变一些识别信息,它看起来像我结束了不正确的编辑。但基本前提适用。 :)假设它可以进入循环。 – eastydude5 2011-02-23 22:18:43

回答

6

我会使用一个for循环:

for {set d 155} {$d > 0} {incr d -1} { 
    set currentDistance [expr {$d * 0.1}] 

    moveServo $currentHeight 
    set sensorStatus [watchSensor 2] 
    # If we've found it, stop searching! 
    if {$sensorStatus == 1} break 
} 

这样做的优点是首先对物理不可能性有限制(将机器人研磨成碎片没有意义!)和secondl y用整数进行迭代。第二点至关重要:二进制浮点数是棘手的事情,特别是在迭代0.1时,Tcl(与许多其他语言一样)在内部使用IEEE浮点运算。避免这些问题的方法是迭代整数,并有一些代码转换为浮点数(例如,除以10)。考虑以0.1为单位进行倒计时。 :-)

另一个较小的风格点。将{大括号}放在表达式中,因为它可以提高安全性和性能。 (性能提升是因为运行时知道它不能有奇怪的表达式碎片,这也是不安全的。不是因为它依赖于伺服硬件,所以它在这个代码中至关重要,但是这是个好习惯进入。)

+0

谢谢你的回答,Donal。 – eastydude5 2011-02-23 22:19:23

1

我不知道TCL,但它可能是这个样子:

set currrentDistance 15.5 
set sensorStatus 4 

while {true} { 
    moveServo $currentHeight 
    set sensorStatus [watchSensor 2] 

    if {$sensorStatus == 1} then {break}; 

    set currentDistance [expr $currentDistance - .1] 
}