解魔方的机器人攻略16 – 如何调试

今天已经是2010年了,祝大家新年快乐,新的一年学习好,工作好,身体好,感情好。。。总之一切都好!新年的第一天继续发攻略,希望是一个好的开始 :)

兵法说“代码未动,调试先行”。对于刚接触嵌入式开发的同学来说,把代码写进NXT简直就是杯具,没有断点,不能跟踪,程序挂掉了都不知道是哪里的问题。难怪有些公司招聘程序员的时候,提的要求是“能摸黑写代码”。。。

下面是一个简单的例子,它实现的功能是:每按一次Enter按钮,就显示当前的距离读数,按Escape按钮时退出程序。通过这个例子,你可以知道如何用NXT的面板按钮或传感器来做断点工具,用LCD显示屏来跟踪数据。因为不舍得把萝卜头全拆了,所以用好拆的部分来做例子,先凑合看看:)

import lejos.nxt.*;
import lejos.nxt.comm.*;

/**
 * First Sample: Read distance by the control of buttons
 * @author ChenWu
 * @see LCD
 * @see UltrasonicSensor
 * @see Button
 */
public class DebugSample
{
 static UltrasonicSensor distance=new UltrasonicSensor(SensorPort.S1);

 public static void main (String[] aArg) throws Exception
 {
  while(!Button.ESCAPE.isPressed())
  {
   LCD.drawString("Distance=" + distance.getDistance()+"  ",0,3);

   //Remove this while condition if you want to get dynamic value
   while(!Button.ESCAPE.isPressed() && !Button.ENTER.isPressed())
   {
    Thread.sleep(100);
   }
  }
 }
}

把文件保存为 DebugSample.java,在命令提示符中运行下面的命令,把程序写入NXT:
nxjc DebugSample.java
nxj -r DebugSample

把程序写入NXT,这个步骤也可以在Eclipse中完成

把程序写入NXT,这个步骤也可以在Eclipse中完成

这段程序很短,有经验的老鸟们应该一目了然了。新同学请看下面的说明,没Java基础的请自己先补习一下吧 :)

1.  头两行import是导入Lejos的函数库,导入之后才能调用lejos的各种API。

2.  NXT的显示屏幕是一个分辨率为100×64的LCD屏幕,LCD屏幕一共可以显示8行16列ASCII字符,可以用内置的LCD对象来控制显示内容。例如显示一串字符的命令是:
LCD.drawString(“string”,x,y);
这个命令表示显示string的开始位置坐标是(x,y),下标从0开始。例如(0,3)表示从第4行的第1列开始显示。

显示的时候如果原来的位置有文字,会被覆盖掉,但是不会清除其他地方的文字。(我的程序里面distance后面加了两个空格,理由请自己思考一下)另外几个常用的方法是 drawInt 和 clear,更多的方法可以参考相应的API文档

如果你想显示非标准的字体,甚至是一副图片,可以使用Image类,通过二进制数组进行像素级别的控制

3.  UltrasonicSensor 也是Lejos的内置对象,封装了超声波测距传感器的各种方法和属性。用distance.getDistance()函数就可以返回一个整数,这个数表示眼睛到物体之间的厘米,理论上范围是1到255。如果我们把眼睛捂上,或者距离超过255cm,它的读数都是255。

4.  SensorPort.S1表示该传感器是接在1号接口上(看NXT主机下面1~4的编号)

5.  Button用来响应面板上各按键的交互事件,button的对应关系看下面这个图

Button的对应关系

Button的对应关系

Button.ESCAPE.isPressed() 用来判断按键是否被按下了。另外一个常用的方式是 Button.ESCAPE.waitForPress(); 程序运行到这句函数时会被挂起,直到按钮按下时才会继续执行后面的语句。

6. 如果你觉得每次都按一下Enter键很烦,可以把中间的那个while条件注释掉(当然对应的一对大括号也要去掉)。这样一来屏幕就会动态显示当前的实时距离,按下Escape键时退出。

7. Thread.sleep(100)表示程序运行到这里时,会暂停100毫秒然后继续执行后面的代码。它的作用是让你有读数的时间,否则屏幕上的读数会飞快的变换,根本看不清。

看看效果如何:

按下Enter时,刷新距离读数,按下Escape时,程序退出

按下Enter时,刷新距离读数,按下Escape时,程序退出

cnBeta有位网友认为这个距离传感器是冗余设计,正好我在这里介绍一下这个“眼睛”的作用:

1. 用来判断转台上有没有魔方,放了魔方的时候测量的距离是14~15,没有魔方的时候是18~20。通过这个值先变大,然后再变小,就可以知道是有人先把魔方拿走,然后再放回来,于是激活下一轮扫描颜色

2. 用来做断点调试使用。在搭建萝卜头的初期,它的胳膊经常骨折,颜色也经常读错。为了便于调试,我把眼睛设置成了一个中断开关。当我需要它暂停的时候,就用手捂住它的眼睛,它就会停下来,把手移开,它又可以继续工作。使用的代码如下:

public static void WaitForNextAction()throws Exception
{
 while(distance.getDistance()>150)
 {
  Thread.sleep(100);
 }
 return;
}

通过这个例子,你可以了解如何在制作乐高机器人的过程中进行单步调试。如果你有其他的好方法,请一定在这里留言,让大家一起分享,多谢多谢! :)

今天就先介绍这些,感谢新年第一天还来光临小站的热心朋友,祝大家新年好!



对 “解魔方的机器人攻略16 – 如何调试” 的 14 条 评论

  1. 小宏 说:

    虽然我还没买,但还是谢谢了!

    新年快乐~

  2. zeus 说:

    拜读到此,持续跟进,留个脚印,关注博主!

  3. dot 说:

    新年快乐,有机会一定试试你的造人术

  4. zeus 说:

    足球机器人吸球/弹射装置纯乐高解决方案
    http://www.robotdiy.com/article.php?sid=221

    刚出去转悠找到这个,在你这里留个档

  5. zeus 说:

    又找到个国产的组件,看上去比9797还更好

    创意之星™ 机器人套件
    http://robot.up-tech.com/ch/ProductView.asp?ID=48

  6. 散步的狼 说:

    新年快乐!
    关注中。昨天弄了下LDD那个软件 不太会用 零件不能准确放到位 有的干脆就放不进去 不知道怎么弄 网上也没找到相关资料 听说有个高级版的软件 mlcad 下载了 还没弄明白怎么配置呢

  7. zeus 说:

    就是,博创的太贵了。
    ps:我从6点开始看你得这篇文章,然后找相关资料。不吃不喝到现在4个小时了。先去吃饭了。
    你看看这些,nxt的可玩性还多也
    http://pemiamos.blogbus.com/logs/52763191.html
    http://www.semia.com/blog/u/legoman/archives/2009/21233.html

  8. cowskin 说:

    新年快乐~
    深夜造访~该系类blog读了一遍~非常棒!

  9. edwo 说:

    我也是魔友一枚!会继续跟进你的作品的,如果有可能也想向你学习做一个出来!

  10. delectate 说:

    最关心的算法只字没写

    写的倒是不少~无关痛痒的居多

  11. 老男孩的粉丝 说:

    程序19行,

    LCD.drawString(Distance=” + distance.getDistance()+” “,0,3);
    应为
    LCD.drawString(“Distance=” + distance.getDistance()+” “,0,3);

发表评论

可以使用下列 XHTML 标签:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>