LeJOS NXT 编程声波传感器
LeJOS NXT Programming Sonic Sensor
我正在尝试制作一个连接了超声波传感器的 NXT 机器人。它必须一直行驶到距离为 15,然后发动机必须停止。停止后它必须转动,但它不起作用。
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
try {
Motor.B.rotate(-1500 , true);
Motor.C.rotate(-1500 , true);
} catch (Exception E){}
while ( ultra.getDistance() < 15 ) {
Motor.B.backward();
Motor.C.backward();
}
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
我的旧代码也不起作用:
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
try {
Motor.B.rotate(-720);
Motor.C.rotate(-720);
} catch (Exception E){}
for (int i = 0; i < 5; i++)
{
LCD.drawString("Distance : "+ultra.getDistance(), 0, i);
Thread.sleep(2000);
int maxDistance = ultra.getDistance();
if (maxDistance < 15){
Motor.B.stop();
Motor.C.stop();
}
}
Button.waitForAnyPress();
}
}
假设
好的,从表面上看,您的代码可能没有按照您的要求执行。 (以后,在 Stack Overflow 上写问题时,请详细说明预期的行为是什么,以及您看到的错误行为是什么。无论如何,这通常是我们问您的前两个问题。)
首先,您需要确保您的 NXT 套件已正确设置,B 和 C 上有两个电机,S1 上有传感器。如果是这样,请继续阅读。
代码解释
电机指令:
try {
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
} catch (Exception E) {}
看起来它们是有效的电机指令……但是等等!您使用的是双轮机器人,电机连接到两个 指向相反方向 的轮子?但是您使用相同的距离 和方向 作为电机的极限角度!如果你的轮子相互对立,那么这只会让机器人旋转一圈。
注意:由于您的电机配置正确,如评论中所写,请忽略此部分。
如果您通过将正极变为负极来改变其中一个电机的方向,那么您将让它们齐心协力使您的机器人向前移动(或向后移动,如果您换错了!)
此外,请记住将 true
作为
中的第二个参数传递
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
根据 Javadoc(强调我的),以非常具体的方式实现此功能:
If immediateReturn
is true, method returns immediately and the motor stops by itself.
If any motor method is called before the limit is reached, the rotation is canceled.
第一句话的意思是这就是我们想要的:它告诉我们的电机自己找到合适的极限角度,但不要让我们的程序等待它。但是,第二句的意思是,如果调用任何其他电机命令,它将停止移动到给定的极限角度。是啊,没错。接下来的几行让我们停止移动电机并按照他们说的去做。
现在,这段代码有问题有两个原因:
while (ultra.getDistance() < 30) {
Motor.B.backward();
Motor.C.backward();
}
首先,这些命令将立即停止我们之前的两个电机命令的执行,这基本上意味着电机将直接跳到“向后”并循环直到距离传感器读数大于或等于 30
.这实际上是我们想要的,但我们还需要更多...
其次,在您的传感器读取的距离大于 30
后,您的电机永远不会被告知停止!因此,即使您的程序正在向您显示距离,并等待您按下按钮,它仍会移动!
一个解决方案
好的,有几点需要更改:
- 您的初始电机命令被后来告诉它移动到正确位置的命令所阻止。
- 你的马达不会在它们应该停止的时候停止。
以下是您的代码,经过编辑以解决其中的每一个问题。我在进行更改的地方添加了注释,以向您展示我所做的更改。
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
// No initial motor movement (because it did nothing anyway)
// We change this to approach from either direction.
while (ultra.getDistance() != 30) {
// Check whether it's behind or ahead of it.
// Assuming that B- and C- increase distance, and B+ and C+ decrease it (depends on robot configuration).
// This is called a feedback loop, by the way.
if (ultra.getDistance() < 30) { // Move forward (distance+)
Motor.B.backward();
Motor.C.backward();
} else { // Move backward (distance-)
Motor.B.forward();
Motor.C.forward();
}
}
// We only get here when the distance is right, so stop the motors.
Motor.B.stop();
Motor.C.stop();
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
现在,这段代码并不完美;它可能会在光滑的表面上前后摆动(由于施加的扭矩不同,它可能会稍微向左或向右转动),或者如果传感器错过了正确的位置并且机器人超过了它。
此代码也不会等到机器人稳定在给定位置,直到传感器第一次报告正确的位置。同样,如果车轮没有足够的牵引力、电机设置为平稳加速或电机 运行 速度过高,这可能会导致稍微打滑。
要纠正这些缺陷,您需要一种更高级的反馈回路来解决加速度和滑移问题,并且您需要等到机器人在短时间内稳定在正确的位置之后停止电机。
但是,可以这么说,这会让您朝着正确的方向前进。
编辑更正了驱动电机的方向性,如评论中所述。
我正在尝试制作一个连接了超声波传感器的 NXT 机器人。它必须一直行驶到距离为 15,然后发动机必须停止。停止后它必须转动,但它不起作用。
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
try {
Motor.B.rotate(-1500 , true);
Motor.C.rotate(-1500 , true);
} catch (Exception E){}
while ( ultra.getDistance() < 15 ) {
Motor.B.backward();
Motor.C.backward();
}
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
我的旧代码也不起作用:
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
try {
Motor.B.rotate(-720);
Motor.C.rotate(-720);
} catch (Exception E){}
for (int i = 0; i < 5; i++)
{
LCD.drawString("Distance : "+ultra.getDistance(), 0, i);
Thread.sleep(2000);
int maxDistance = ultra.getDistance();
if (maxDistance < 15){
Motor.B.stop();
Motor.C.stop();
}
}
Button.waitForAnyPress();
}
}
假设
好的,从表面上看,您的代码可能没有按照您的要求执行。 (以后,在 Stack Overflow 上写问题时,请详细说明预期的行为是什么,以及您看到的错误行为是什么。无论如何,这通常是我们问您的前两个问题。)
首先,您需要确保您的 NXT 套件已正确设置,B 和 C 上有两个电机,S1 上有传感器。如果是这样,请继续阅读。
代码解释
电机指令:
try {
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
} catch (Exception E) {}
看起来它们是有效的电机指令……但是等等!您使用的是双轮机器人,电机连接到两个 指向相反方向 的轮子?但是您使用相同的距离 和方向 作为电机的极限角度!如果你的轮子相互对立,那么这只会让机器人旋转一圈。
注意:由于您的电机配置正确,如评论中所写,请忽略此部分。
如果您通过将正极变为负极来改变其中一个电机的方向,那么您将让它们齐心协力使您的机器人向前移动(或向后移动,如果您换错了!)
此外,请记住将 true
作为
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
根据 Javadoc(强调我的),以非常具体的方式实现此功能:
If
immediateReturn
is true, method returns immediately and the motor stops by itself.If any motor method is called before the limit is reached, the rotation is canceled.
第一句话的意思是这就是我们想要的:它告诉我们的电机自己找到合适的极限角度,但不要让我们的程序等待它。但是,第二句的意思是,如果调用任何其他电机命令,它将停止移动到给定的极限角度。是啊,没错。接下来的几行让我们停止移动电机并按照他们说的去做。
现在,这段代码有问题有两个原因:
while (ultra.getDistance() < 30) {
Motor.B.backward();
Motor.C.backward();
}
首先,这些命令将立即停止我们之前的两个电机命令的执行,这基本上意味着电机将直接跳到“向后”并循环直到距离传感器读数大于或等于 30
.这实际上是我们想要的,但我们还需要更多...
其次,在您的传感器读取的距离大于 30
后,您的电机永远不会被告知停止!因此,即使您的程序正在向您显示距离,并等待您按下按钮,它仍会移动!
一个解决方案
好的,有几点需要更改:
- 您的初始电机命令被后来告诉它移动到正确位置的命令所阻止。
- 你的马达不会在它们应该停止的时候停止。
以下是您的代码,经过编辑以解决其中的每一个问题。我在进行更改的地方添加了注释,以向您展示我所做的更改。
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
// No initial motor movement (because it did nothing anyway)
// We change this to approach from either direction.
while (ultra.getDistance() != 30) {
// Check whether it's behind or ahead of it.
// Assuming that B- and C- increase distance, and B+ and C+ decrease it (depends on robot configuration).
// This is called a feedback loop, by the way.
if (ultra.getDistance() < 30) { // Move forward (distance+)
Motor.B.backward();
Motor.C.backward();
} else { // Move backward (distance-)
Motor.B.forward();
Motor.C.forward();
}
}
// We only get here when the distance is right, so stop the motors.
Motor.B.stop();
Motor.C.stop();
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
现在,这段代码并不完美;它可能会在光滑的表面上前后摆动(由于施加的扭矩不同,它可能会稍微向左或向右转动),或者如果传感器错过了正确的位置并且机器人超过了它。
此代码也不会等到机器人稳定在给定位置,直到传感器第一次报告正确的位置。同样,如果车轮没有足够的牵引力、电机设置为平稳加速或电机 运行 速度过高,这可能会导致稍微打滑。
要纠正这些缺陷,您需要一种更高级的反馈回路来解决加速度和滑移问题,并且您需要等到机器人在短时间内稳定在正确的位置之后停止电机。
但是,可以这么说,这会让您朝着正确的方向前进。
编辑更正了驱动电机的方向性,如评论中所述。