hwang090919-

Download Report

Transcript hwang090919-

機器人新視界 NXC與NXT
曾吉弘
今天要談什麼
1.
2.
3.
4.
5.
6.
7.
NXC-針對LEGO量身訂作的C語言
BricxCC-簡單好用的程式環境
讓機器人動起來
程式結構
感應器
馬達
進階I/O控制
阿吉是誰
• 台北教育大學 玩具與遊戲設計 碩士
– A Study of Developing the Technological Curiosity
Inventory and Its Application to LEGO Hands-on
Learning.
• 政治大學 資訊管理 學士
• 現於台灣大學 土木工程學系 康仕仲老師研究室
專任機器人研究助理
– Educational Robot tutorial and curriculum design
– Mobile Robot
– Robotarm
CAVE做過什麼
• 2009出版 機器人新視界: NXC與NXT, 使用 C
語言來控制LEGO NXT智慧型主機
• 2008成立CAVE 小小原始人 科學創意工坊, 致
力推動高階機器人教育. 使用C, Java,
LabVIEW等程式語言.
• 2000~2007 貝登堡國際 資深機器人講師
CAVE要做什麼
• 預計出版: Comprehensive LEGO Silver
book: LEGO機構口袋書
• 預計出版: Darkside of LEGO NXT: LabVIEW
killer apps.
• 預計出版: Java being: leJOS on NXT
• Work on I2C devices
• 持續舉辦下午茶會
怎麼找到CAVE
• Blog : CAVE + LEGO
• Youtube : allelujahnissin
• Picasa : allelujahnissin
• facebook : allelujahnissin
康老師研究室
• 台灣大學土木系電腦輔助工程組
– 教育用機器人 – LEGO NXT
– PC-based robot
– Robotarm
– 服務型機器人
LEGO MindStorms NXT
 NXT與RCX比較
NXT
RCX
上市時間
1999
2005
處理器
Hitachi H8/3292 微控制器
32位元ARM7微處理器,8位元輔助處理器
記憶體
8K ROM 32KRAM
傳輸方式
紅外線傳輸
256 K快閃記憶體, 64 K RAM4 K快閃記憶體,
512 B RAM
USB 2.0 (PC – NXT),藍芽
連接線
2 wire connector system
6 wire digital platform.
I/O端子
3個輸入端,3個輸出端
4個輸入端,3個輸出端
LCD
43個顯示單位
64 x 100像素的可程式化液晶顯示面板
電力方式
3號電池 x 6
RCX 2.0可外接電源
3號電池 x 6
充電鋰電池
9
Mindstorms (NXT-G)
Robolab
RobotC
NXJ (Java)
LabVIEW
 NXC與NXT-G比較
NXC
NXT-G
程式介面
文字式(BrixCC)
圖像式
適用年齡
12歲以上
8歲以上
取得方式
依產品附上
支援其他感應器
免費下載
http://bricxcc.sourceforge.net/
有
上手難易
有一定門檻
簡單
功能性
強大
中等
除錯
常常需要
幾乎不用
15
有
Programming interface
Graphical
• NXT-G
Text based
• NXC
• MicroSoft
• RobotC
– Robotic Developer Studio
• Java
• National Instruments
– LabVIEW NXT toolkit
• Others: PbLua, php…
Brief comparison
MSRDS
功能
NXC
LabVIEW
Java
NXT-G
學習難度
NXC
•Not eXactly C by John C. Hansen.
•Bricx Command Center (FREE!)
•C-based language
•Highly integrated with 3rd party I/O devices.
18
 NXT介面介紹
輸出端(馬達)
•藍芽
•USB
•名稱
•執行狀態圖示
•電池
確定/開啟
USB 連接埠
圖示
發聲器
選擇
返回/關機
輸入端(感應器)
19
Bricx Command Center
20
Important settings and interfaces
• Preferences
– compiler, font, code completion.
•
•
•
•
•
Direct control
Watching the brick
Brick Joystick
NXT Explorer
NXT Screen
First Robot
http://ldd.lego.com/
22
First Program
010203040506070809-
task main()
{
OnFwd(OUT_A, 75);
OnFwd(OUT_B, 75);
Wait(4000);
OnRev(OUT_AB, 75);
Wait(4000);
Off(OUT_AB);
}
23
F5 Compile
F6 Download
F7 Run
24
Macro
0102030405060708091011-
#define MOVE 1000
#define TURN 850
task main()
{
OnFwd(OUT_BC,75) ;
Wait(MOVE);
OnRev(OUT_BC,75);
Wait(TURN);
Off(OUT_BC);
}
25
Repeat loop
01020304050607080910111213-
#define MOVE 1000
#define TURN 850
task main()
{
repeat(5)
{
OnFwd(OUT_BC,75) ;
Wait(MOVE);
OnRev(OUT_BC,75);
Wait(TURN);
}
Off(OUT_BC);
}
26
Nested loop
010203040506070809101112131415161718-
#define MOVE 1000
#define TURN 850
task main()
{
repeat(2)
{
PlayTone(440,50);
Wait (1000);
repeat (5)
{
OnFwd(OUT_BC,75) ;
Wait(MOVE);
OnRev(OUT_BC,75);
Wait(TURN);
}
}
Off(OUT_BC);
}
27
Control Structure and Variable
Variable
01- task main()
02- {
03int a = 3;
04while(a < 5)
05{
06OnFwd(OUT_BC,75) ;
07Wait(1000);
08PlayTone(440,50);
09a++;
10}
11Off(OUT_BC) ;
12- }
29
while
01020304050607080910111213141516171819-
#define MOVE_TIME 500
#define TURN_TIME 360
task main()
{
while(true)
{
OnFwd(OUT_AC, 75);
Wait(MOVE_TIME);
if (Random(2) == 0)
{
OnRev(OUT_C, 75);
}
else
{
OnRev(OUT_A, 75);
}
Wait(TURN_TIME);
}
}
30
do while
01020304050607080910111213141516-
int move_time, turn_time, total_time;
task main()
{
total_time = 0;
do
{
move_time = Random(1000);
turn_time = Random(1000);
OnFwd(OUT_AC, 75); Wait(move_time);
OnRev(OUT_C, 75); Wait(turn_time);
total_time += move_time;
total_time += turn_time;
} while (total_time < 20000);
Off(OUT_AC);
}
31
SENSORS
Touch sensor
• 語法: SetSensorTouch(S1);
33
01020304050607
080910111213-
task main()
{
SetSensor(S1,SENSOR_TOUCH);
while(true)
{
OnFwd(OUT_AC, 50);
until (SENSOR(S1) == 1);
OnRev(OUT_AC, 50);
Wait( 500);
OnFwd(OUT_A, 50);
Wait(1000);
}
}
34
Sound sensor
• 語法: SetSensorSound(S2);
35
01020304050607
080910111213-
task main()
{
SetSensor(S1,SENSOR_SOUND);
while(true)
{
If (SENSOR(S1) >90);
PlayTone(440, 50);
Wait( 500);
}
}
36
Ultrasonic sensor
• 語法:SetSensorLowspeed(S4);
37
0102030405060708091011121314151617181920212223242526272829-
#define DISTANCE 15 //cm
task main()
{
SetSensorLowspeed(IN_4);
while(true)
{
OnFwd(OUT_AC,20);
if(SensorUS(IN_4) < DISTANCE)
{
Off(OUT_AC);
OnRev(OUT_AC,20);
Wait(800);
Off(OUT_AC);
}
else if(SensorUS(IN_4) == DISTANCE)
{
Off(OUT_AC);
PlayTone(440,50);
Wait(1000);
}
else if(SensorUS(IN_4) > DISTANCE)
{
Off(OUT_AC);
OnFwd(OUT_AC,20);
Wait(800);
Off(OUT_AC);
}
}
}
38
Rotation sensor
語法:RotateMotor(OUT_Port , Speed , Degree);
0102030405060708-
task main()
{
int x;
RotateMotor(OUT_A, 75, 180); // 正轉180度
x = MotorTachoCount(OUT_A);
NumOut(20, LCD_LINE3, x);
Wait(3000);
}
Give a try!
x = 180?
39
Light sensor
• 語法:SetSensorLight(S3);
40
01020304050607
080910111213-
task main()
{
//
SetSensorLight(S3);
SetSensor(S1,SENSOR_LIGHT);
while(true)
{ ClearScreen();
TextOut(0,20,"Light is");
NumOut(60,20,Sensor(S3));
if (Sensor(S3) >40)
{
PlayTone(440, 50); //beep
}
Wait( 200); //0.2 sec
}
}
41
第六章 大大小小的任務
• task
start
Precedes()
mutex Acquire() 與 Release()
• subroutine
• inline function
inline int B( 參數 )
{
statements
return x;
}
sub FunctionName (data type varible)
42
Macro
我們已經知道如何用 define 來定義一個常數,現在我們還可
以用 define 來定義任何一個程式片段。
01020304050607080910111213-
#define turning \
OnRev(OUT_B, 75); Wait(3400);OnFwd(OUT_BC, 75);
task main()
{
OnFwd(OUT_BC, 75);
Wait(1000);
turning;
Wait(2000);
turning;
Wait(1000);
turning;
Off(OUT_BC);
}
43
第七章 馬達面面觀
NXC的馬達指令可分為4大類:
1.unregulated
2.speed regulation
3.synchronized
4.tachometer-limited
• 怎麼停 大不同
Off();
Float(); = Coast();
01020304050607080910-
task main()
{
OnFwd(OUT_AC, 75);
Wait(500);
Off(OUT_AC);
Wait(1000);
OnFwd(OUT_AC, 75);
Wait(500);
Float(OUT_AC);
}
使用Off()時,NXT會在瞬間施加一個反向電流給馬達來達到煞車的效果。
但如使用Float()的話,NXT只有停止對馬達的供電,但馬達本身因為旋轉
而具有轉動慣量而會再轉動一點點才停下。
• 無控制模式(unregulated)
OnFwd();
OnRev();
• 控制模式(regulation)
OnFwdReg(輸出端,速度,控制模式) ;
OnRevReg (輸出端,速度,控制模式) ;
控制模式的參數
OUT_REGMODE_IDLE
OUT_REGMODE_SPEED
OUT_REGMODE_SYNC
• 速度控制模式(speed regulation)
OnFwdReg(OUT_C, 40, OUT_REGMODE_SPEED);
01020304050607080910-
task main()
{
OnFwdReg(OUT_A, 40, OUT_REGMODE_IDLE);
OnFwdReg(OUT_C, 40, OUT_REGMODE_SPEED); //會自動增強電力
while(true)
{
NumOut(10, LCD_LINE1, MotorActualSpeed(OUT_A));
NumOut(10, LCD_LINE2, MotorActualSpeed(OUT_C));
}
}
同步模式(synchronized)
OnFwdReg(OUT_AC, 40, OUT_REGMODE_SYNC);
兩顆馬達同步
•
•
•
•
•
•
•
•
•
•
•
task main()
{
//
OnFwdReg(OUT_B, 40, OUT_REGMODE_IDLE);
//
OnFwdReg(OUT_C, 40, OUT_REGMODE_SPEED);
OnFwdReg(OUT_BC, 40, OUT_REGMODE_SYNC);
while(true)
{
NumOut(10, LCD_LINE1, MotorActualSpeed(OUT_B));
NumOut(10, LCD_LINE2, MotorActualSpeed(OUT_C));
}
}
綜合比較:IDLE、SPEED與SYNC
0102030405060708091011121314151617-
task main()
{
OnFwdReg(OUT_AC,50,OUT_REGMODE_IDLE);
Wait(2000);
Off(OUT_AC);
PlayTone(4000,50);
Wait(1000);
ResetTachoCount(OUT_AC);
OnFwdReg(OUT_AC,50,OUT_REGMODE_SPEED);
Wait(2000);
Off(OUT_AC);
PlayTone(4000,50);
Wait(1000);
OnFwdReg(OUT_AC,50,OUT_REGMODE_SYNC);
Wait(2000);
Off(OUT_AC);
}
同步模式的轉彎百分比
OnFwdSync();
OnRevSync();
OnFwdSync();與OnRevSync();是另一組同步指令:
OnFwdSync(輸出端,速度,轉彎百分比);
0 : 直走
50 : 以某輪為圓心轉
100 : 以兩輪中點為圓心來轉彎
01020304050607080910111213141516-
task main()
{
PlayTone(5000,30);
OnFwdSync(OUT_AC,50,0);
Wait(1000);
PlayTone(5000,30);
OnFwdSync(OUT_AC,50,50);//百分比增為50
Wait(1000);
PlayTone(5000,30);
OnFwdSync(OUT_AC,50,-50); //百分比為-50
Wait(1000);
PlayTone(5000,30);
OnRevSync(OUT_AC,50, -100); //馬達反轉,百分比為-100
Wait(1000);
Off(OUT_AC);
}
轉速表模式(tachometer-limited)
RotateMotor(輸出端,速度,角度);
0102030405060708-
task main()
{
RotateMotor(OUT_A, 50,360); //A馬達逆時鐘轉一圈
RotateMotor(OUT_A, 50,-360); //A馬達順時鐘轉一圈
RotateMotor(OUT_A, -50,-360); //A馬達逆時鐘轉一圈
RotateMotor(OUT_C, 50,-360); //C馬達順時鐘轉一圈
RotateMotor(OUT_C, -50,360); //C馬達順時鐘轉一圈
}
延伸指令-RotateMotorEx();
RotateMotorEx(輸出端,速度,轉動角度,轉彎百分比,是否同步,是否煞車);
RotateMotorEx(OUT_AC, 75, 180, 0, true, true);
開啟NXT軟體
關閉範例指引
開啟範例指引
建立新程式
完整工具箱
常用工具箱
使用範例指引
依照範例指引製作程式
教導與重做指令
放音
教導與重做
馬達
sensor
新增變數名稱
變數
新增變數名稱
顯示(3+4)x5
撞到手停止
撞到手停止後退
走到桌邊停止(懸崖勒馬)
走到桌邊後退(懸崖勒馬)
走過3條線後停止
走到桌邊停止
• task main()
• {
•
SetSensorLight(S3);
•
OnFwd(OUT_BC, 40);
•
while(true)
•
{
•
ClearScreen();
•
NumOut(60,20,Sensor(S3));
•
if (Sensor(S3)<20)
•
{
•
Off(OUT_BC);
•
}
•
}
• }
走到桌邊後退
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
task main()
{
SetSensorLight(S3);
OnFwd(OUT_BC, 40);
while(true)
{
ClearScreen();
NumOut(60,20,Sensor(S3));
if (Sensor(S3)<20)
{
OnRev(OUT_BC, 40);
Wait(500);
OnFwd(OUT_BC, 40);
//
Off(OUT_BC);
}
}
}
走到桌邊後退轉向再走
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#define edge 35
sub MoveFwd(int pwr){
OnFwd(OUT_AC, pwr);
Wait(200);
}
sub MoveBack(int pwr){
OnRev(OUT_AC, pwr);
Wait(1500);
}
sub MoveL(int pwr){
OnFwd(OUT_A, pwr);
Off(OUT_C);
Wait(1000);
}
sub MoveR(int pwr){
OnFwd(OUT_C, pwr);
Off(OUT_A);
Wait(100);
}
task main()
{
SetSensorLight(S1);
int a;
while(true)
{
// ClearScreen();
NumOut(60,20,Sensor(S1));
a=Sensor(S1);
if (a < edge)
{
MoveBack(30);
//out
MoveL(30);
//out
} else {
MoveFwd(30);
}
}
}
跟著手走
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#define dist 20
task main()
{
SetSensorLowspeed(S4);
int a;
OnFwd(OUT_BC, 40);
while(true)
{
ClearScreen();
NumOut(60,20,SensorUS(S4));
a=SensorUS(S4);
if (a<dist)
{
OnRev(OUT_BC, 40); //靠近時後退
Wait(500);
} else {
OnFwd(OUT_BC, 40);
Wait(500);
}
}
}
聲控車
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#define dist 20
task main()
{
SetSensorSound(S2);
int a;
// OnFwd(OUT_BC, 40);
while(true)
{
ClearScreen();
NumOut(60,20,Sensor(S2));
a=Sensor(S2);
if (a > 50)
{
OnFwd(OUT_BC, a);
Wait(200);
}
Off(OUT_BC);
}
}
聲控車進階版
•
•
•
•
•
#define dist 20
sub haha(int pwr, int time){
OnFwd(OUT_BC, pwr);
Wait(time);
}
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
task main()
{
SetSensorSound(S2);
int a;
// OnFwd(OUT_BC, 40);
while(true)
{
ClearScreen();
NumOut(60,20,Sensor(S2));
a=Sensor(S2);
if (a > 50)
{
haha(a, a);
}
Off(OUT_BC);
}
}
沿著牆走機器人
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#define near 18
#define far 25
sub MoveFwd(int pwr){
OnFwd(OUT_AC, pwr);
Wait(200);
}
sub MoveL(int pwr){
OnFwd(OUT_A, pwr);
Off(OUT_C);
Wait(300);
}
sub MoveR(int pwr){
OnFwd(OUT_C, pwr);
Off(OUT_A);
Wait(300);
}
task main()
{
SetSensorLowspeed(S1);
int a;
while(true)
{
ClearScreen();
NumOut(60,20,SensorUS(S1));
a=SensorUS(S1);
if (a < near)
{
MoveL(80);
} else if ( a > far)
{
MoveR(80);
} else {
MoveFwd(40);
}
}
}
沿著圓形封閉軌跡走機器人
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#define line 35
sub MoveFwd(int pwr){
OnFwd(OUT_AC, pwr);
Wait(100);
}
sub MoveL(int pwr){
OnFwd(OUT_A, pwr);
Off(OUT_C);
Wait(100);
}
task main()
{
SetSensorLight(S1);
int a;
while(true)
{
// ClearScreen();
NumOut(60,20,Sensor(S1));
a=Sensor(S1);
if (a > line)
{
MoveL(30);
//out
} else {
MoveFwd(30);
}
}
}
雙光感車by祥瑞
•
http://tw.myblog.yahoo.com/lego-caveschool/article?mid=1759&prev=1769&next=1756
#define H 60
#define L 40
task main(){
SetSensorLight(S1);
SetSensorLight(S2);
SetSensorTouch(S3);
SetSensorTouch(S4);
int S1_N;
int S2_N;
int S1_Br;
int S1_Da;
int S2_Br;
int S2_Da;
until(Sensor(S3)==1);
S1_Br=Sensor(S1);
S2_Da=Sensor(S2);
until(Sensor(S4)==1);
S1_Da=Sensor(S1);
S2_Br=Sensor(S2);
S1_N=(S1_Br+S1_Da)/2;
S2_N=(S2_Br+S2_Da)/2;
while(true){
if(Sensor(S1)>S1_N && Sensor(S2)>S2_N){
OnRev(OUT_AC, L);
}
else if(Sensor(S1)>S1_N && Sensor(S2)<=S2_N){
OnRev(OUT_A, H);
//OnRev(OUT_C, L);
Off(OUT_C);
Wait(500);
}
else if(Sensor(S1)<=S1_N && Sensor(S2)>S2_N){
Off(OUT_A);
//OnRev(OUT_A, L);
OnRev(OUT_C, H);
Wait(500);
}
else{
OnRev(OUT_AC, L);
//PlayTone(440, 50);
}
}
}
雙光感車進階by祥瑞
http://tw.myblog.yahoo.com/jw!tdWkVrqREQGy.hGxtJ3wsdY2/article?mid=1798
•
•
#define speed 40
#define scaleChange 20
task main() {
SetSensorLight(S1);
SetSensorLight(S2);
SetSensorLight(S3);
int vL = Sensor(S1);
int vM = Sensor(S2);
int vR = Sensor(S3);
int scaleL = (vL+vM)/2;
int scaleR = (vR+vM)/2;
while(true) {
if((Sensor(S1)-Sensor(S2))>=scaleChange || (Sensor(S3)-Sensor(S2))>=scaleChange) {
vL = Sensor(S1);
vM = Sensor(S2);
vR = Sensor(S3);
scaleL = (vL+vM)/2;
scaleR = (vR+vM)/2;
}
}
}
if(vL>scaleL && vR>scaleR) {
OnRev(OUT_AC, speed);
}
else if(vL>scaleL && vR<=scaleR) {
OnRev(OUT_A, speed);
Off(OUT_C);
until(Sensor(S2)
}
else if(vL<=scaleL && vR>scaleR) {
OnRev(OUT_C, speed);
Off(OUT_A);
until(Sensor(S2)
}
else {
PlayTone(600, 200);
OnRev(OUT_AC, speed);
}
遙控車by祥瑞
http://tw.myblog.yahoo.com/lego-caveschool/article?mid=1903&prev=1&next=1895
3rd party sensors
結語
• Passion
• Open mind
• Hard Work