Hardware components | ||||||
| × | 1 |
This is my first create Humanoid Robot. The aim is using products can be easily purchased in the market to create a low cost but effective Humanoid.
I am an robot fans and fancy on Humanoid robots like Roboone in Japan, IRC in Korea. Actually I have come up to Version 4 now which is a professional battle humanoid robot fighting in these big league but I hope to share it step by step.
The V1 Openbot is a testing humanoid using 18kg/cm torque servo. These servo can be purchased easily in the market. The body frame is made of fibre board. You can cut it with CNC or laser cut (be aware : laser cut fibre board will produce toxic gas).
The control board is using arduino board with servo port extension and I can remote control it with my ps2 controller.
Here is some of the demo video
All the basic motion requirement can be achieved and this humanoid can be made under USD1,000
Hope you like this robot and please feel free to comment and share your idea. XD
You can also go to the following facebook page to see some update for the humanoid robot project.:P
ps2 controller code(By QDS Controller Board)
Arduino/*
--------------------------------------------------------------------------------
Standard Digital Pad
BYTE CMND DATA
01 0x01 idle
02 0x42 0x41
03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
04 idle data SLCT STRT UP RGHT DOWN LEFT
05 idle data L2 R2 L1 R1 /\ O X |_|
All Buttons active low.
--------------------------------------------------------------------------------
Analogue Controller in Red Mode
BYTE CMND DATA
01 0x01 idle
02 0x42 0x73
03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
04 idle data SLCT JOYR JOYL STRT UP RGHT DOWN LEFT
05 idle data L2 R2 L1 R1 /\ O X |_|
06 idle data Right Joy 0x00 = Left 0xFF = Right
07 idle data Right Joy 0x00 = Up 0xFF = Down
08 idle data Left Joy 0x00 = Left 0xFF = Right
09 idle data Left Joy 0x00 = Up 0xFF = Down
--------------------------------------------------------------------------------
// Button Hex Representations:
//hat
#define psxLeft 0x0080
#define psxDown 0x0040
#define psxRight 0x0020
#define psxUp 0x0010
#define psxStrt 0x0008
#define psxSlct 0x0001
//buttons
#define psxSqu 0x8000
#define psxX 0x4000
#define psxO 0x2000
#define psxTri 0x1000
#define psxR1 0x0800
#define psxL1 0x0400
#define psxL2 0x0100
#define psxR2 0x0200
#define psxJoyL 0x0002
#define psxJoyR 0x0004
//other defines
#define psxAnalog 0x0073
#define psxDigital 0x00FF
*/
/////////////////*****************不可修改***************************
#include "PSX.h" // 导入 Psx 库文件
Psx Psx; // Initializes the library
#define dataPin 6
#define cmndPin 5
#define attPin 4
#define clockPin 3
//#define center 0x7F /////////定义摇杆中间值
////////*********************不可修改**************************
/////所有按键初始化//////////不可修改
int START=0;
int SELECT=0;
int UP=0; //上
int DOWN=0; //下
int LEFT=0; //左
int RIGHT=0; //右
int SQUARE=0; //方框
int CROSS=0; //叉叉
int CIRCLE=0; //圈圈
int TRIANGLE=0; //三角
int L1=0;
int R1=0;
int R2=0;
int L2=0;
int JoyL=0; //摇杆左
int JoyR=0; // 摇杆右
///定义摇杆模拟量
int X1;
int Y1;
int X2;
int Y2;
////////////////////////////所有按键初始化//////////不可修改
int m=100;//定义动作组指定速度比 -200到+200
int t=500; //定义舵机T值作为舵机控制的速度 初始化为500
int p=20;//定义P值的变量值 初始化为500
int s_1=1500;//定义舵机的速率 初始化 为500
int s=0;//动作组 SQ初始化
//int a=0;
int b=0;//模拟模式取反
int b1=0;
int b2=0;
int b3=0;
int c1=0;
int c1_1;//C1取反 STICK LEFT
int c2=0;
int c2_1;//C2取反 STICK RIGHT
int dy=30;//摇杆的速度
int se=0;//SELCET按键状态 按下为1 松开为0
int str=0;
//////////传感器
/*
int xpin=0; //�加速度 X�轴� 接模拟IO A0
int ypin=1; //��加速度 Y 轴�接模拟IO A1
int zpin=2; // 加速度 Z�轴�接模拟IO A2
int a_pin=3; //陀螺仪A 接模拟IO A3
int b_pin=4; //陀螺仪B 接模拟IO A4
int X=0;
int Y=0;
int Z=0;
int A=0;
int B=0;
*/
int c=0;
////////////////////////////
void setup()
{
Psx.setupPins(dataPin, cmndPin, attPin, clockPin); // 设置接收器对应ARDUINO 端口
delay(100); ///等待手柄连线
//Psx.initcontroller(psxAnalog); ///模拟模式 只能选择其中一个或者都不选
// Psx.initcontroller(psxDigital); ///数字模式 只能选择其中一个或者都不选
delay(100); ///等待手柄刷新数据
Serial.begin(115200); ///设置波特率
}
// #<ch> 舵机号ch 0-31
// P<pw> 脉冲宽度pw 500-2500 即舵机的位置
// S<spd> 舵机移动速率spd S只对单个舵机有效
// T<time> 移动到指定位置所需要的时间 T对所有舵机有效
//PL <p> 指定动作场景p, 0 必须指定
//SQ <s> 指定动作组编号 s, 0 - 127
//SM <m> 指定速度比m, –200- 200 不指定为100
//IX <i> 指定启动动作组开始步编号i , 0 - 255。 不指定为0
//PA <a> 设定步之间的暂停时间a, 0 -65535 毫秒。 不指定为0 毫秒
//ONCE 指定执行动作一次。 不指定为循环运行
//L2减速 R2加速 按一次 加/减一档速度
/////////PRESSED////////按下按键 发送一次
/////////RELEASED////////松开按键 发送一次
/////////DOWN////////按住按键不放 一直发送
//程序里面 DOWN ////比如 :if (Psx.digital_buttons & psxStrt) 可屏蔽掉
//但是 PRESSD RELEASED///// 比如:if (Psx.digital_buttons == psxStrt && START==0 ) if (Psx.digital_buttons != psxStrt && START==1) 不可屏蔽
void loop()
{
Psx.poll(); delay(50); // 刷新PSX数据
//////////////////////Start
if (Psx.digital_buttons == psxStrt && START==0 ) ///按下START
{
START=1;
// Serial.println(Psx.digital_buttons, HEX);
Serial.println("pressed_START"); // 发送一次 pressed_START
}
if (Psx.digital_buttons != psxStrt && START==1) //////////松开START
{
START=0;
Serial.println("released_START"); //发送一次 released_START
}
/*
if (Psx.digital_buttons & psxStrt)
{
Serial.println("DOWN_START"); // 按一次 START
}
*/
//////////////////////Select
if (Psx.digital_buttons == psxSlct && SELECT==0) /////按下SELECT
{
SELECT=1;
Serial.println("pressed_Select"); // 发送 按下 SELECT
}
if (Psx.digital_buttons == 0 && SELECT==1) ////松开SELECT
{
SELECT=0;
Serial.println("released_Select"); //发送 松开 SELECT
}
/*
if (Psx.digital_buttons == psxSlct) //一直按住 SELECT
{
Serial.println("DOWN_Select"); // 发送一直按住 SELECT
}
*/
//////////////////////UP
if (Psx.digital_buttons == psxUp && UP==0) // 按一下"上 "
{
UP=1;
Serial.println("pressed_UP"); //按下UP
Serial.println("#5 P1600 T500");//5号舵机用500MS的时间运行到P1600的位置
delay(500);// 延时500MS,以保证该舵机运行到指定位置
Serial.println("#5 P2500 T500");//5号舵机用500MS的时间运行到P2500的位置
delay(500);// 延时500MS,以保证该舵机运行到指定位置
//////////////////////////////5号舵机来回转动/////
}
if (Psx.digital_buttons != psxUp && UP==1)
{
UP=0;
Serial.println("released_Up"); //松开 UP
}
if (Psx.digital_buttons == psxUp)
{
Serial.println("down_Up"); //一直按住
}
//////////////////////DOWN
if (Psx.digital_buttons == psxDown && DOWN==0)
{
DOWN=1;
Serial.println("pressed_DOWN"); ///按下DOWN
Serial.println("#5P1000 #10P1200 #20P1500 T500")//5号、10号、20号舵机转到P1000\P1200\P1500位置
delay(500);//延时500MS,以保证该动作运行完成
Serial.println("#5P1500 #10P2000 #20P2500 T500")//5号、10号、20号舵机转到P1500\P2000\P2500位置
delay(500);//延时500MS,以保证该动作运行完成
/////////////////////////////////5.10.20号舵机来回转动/////
}
if (Psx.digital_buttons != psxDown && DOWN==1)
{
DOWN=0;
Serial.println("released_Down"); //松开 Down
}
if (Psx.digital_buttons == psxDown ) ///////////一直按住DOWN
{
}
/////////////////////LEFT
if (Psx.digital_buttons == psxLeft && LEFT==0) //按一次LEFT
{
LEFT=1;
Serial.println("pressed_Left"); //按一次LEFT
Serial.println("PL0 ");//先停止以前的所有动作组
Serial.println("PL0 SQ2 SM100 ONCE");//然后再以100%速度运行动作组2一次
delay(500);//延时500MS,以保证该动作组运行完成
////////////运行2号动作组一次
}
if (Psx.digital_buttons != psxLeft && LEFT==1) ///松开LEFT
{
LEFT=0;
Serial.println("released_Left"); //松开 LEFT
}
if (Psx.digital_buttons == psxLeft ) //////一直按住LEFT
{
Serial.println("down_Left"); //按住 LEFT
}
/////////////////////RIGHT
if (Psx.digital_buttons == psxRight && RIGHT==0)
{
RIGHT=1;
Serial.println("pressed_RIGHT"); //按一次RIGHT
}
if (Psx.digital_buttons != psxRight && RIGHT==1)
{
RIGHT=0;
Serial.println("released_Right"); //松开 RIGHT
}
if (Psx.digital_buttons == psxRight)
{
}
/////当SELECT=0的时候 按下其他键////****************************************************
if (se==0)
{
/////////////////////TRIANGLE 三角
if (Psx.digital_buttons == psxTri && TRIANGLE==0)
{
TRIANGLE=1;
Serial.println("pressed_TRIANGLE"); //按下三角
}
if (Psx.digital_buttons != psxTri && TRIANGLE==1)
{
TRIANGLE=0;
Serial.println("released_Trlangle"); //松开 三角
}
if (Psx.digital_buttons == psxTri)
{
Serial.println("Down_TRIANGLE"); //一直按住三角
}
/////////////////////CROSS 叉叉
if (Psx.digital_buttons == psxX && CROSS==0)
{
CROSS=1;
Serial.println("pressed_CROSS"); //按一次叉叉
}
if (Psx.digital_buttons != psxX && CROSS==1)
{
CROSS=0;
Serial.println("released_CROSS"); //松开 叉叉
}
if (Psx.digital_buttons == psxX )
{
Serial.println("Down_CROSS"); //一直按住叉叉
}
/////////////////////SQUARE 方框
if (Psx.digital_buttons == psxSqu && SQUARE==0) //按下方框
{
SQUARE=1;
Serial.println("pressed_SQUARE"); //发送按下方框
}
if (Psx.digital_buttons != psxSqu && SQUARE==1) ///松开方框
{
SQUARE=0;
Serial.println("released_SQUARE"); //发送 松开方框
}
if (Psx.digital_buttons == psxSqu ) ////按住方框
{
Serial.println("Down_SQUARE"); //发送按住方框
}
/////////////////////CIRCLE 圈圈
if (Psx.digital_buttons == psxO && CIRCLE==0) ///按一次圈圈
{
CIRCLE=1;
Serial.println("pressed_CIRCLE"); //发送按下圈圈
}
if (Psx.digital_buttons != psxO && CIRCLE==1) ///松开圈圈
{
CIRCLE=0;
Serial.println("released_CIRCLE"); //发送 松开圈圈
}
if (Psx.digital_buttons == psxO) ///一直按住圈圈
{
Serial.println("Down_CIRCLE"); //发送一直按住圈圈
}
////////////////L1
if (Psx.digital_buttons == psxL1 && L1==0) /////按下L1
{
L1=1;//取反
Serial.println("pressed_L1");
}
if (Psx.digital_buttons != psxL1 && L1==1) ///松开L1
{
L1=0;//取反
Serial.println("released_L1"); //发送 松开L1
}
if (Psx.digital_buttons == psxL1) ////////一直按住L1
{
Serial.println("Down_L1");
}
////////////////////R1
if (Psx.digital_buttons == psxR1 && R1==0) //按下R1
{
R1=1;//取反
Serial.println("pressed_R1");
}
if (Psx.digital_buttons != psxR1 && R1==1) ///松开L1
{
R1=0;//取反
Serial.println("released_R1"); //发送 松开L1
}
if (Psx.digital_buttons == psxR1)
{
Serial.println("Down_R1");
}
}
/////////////////////////////////////////////////////////////
/////当SELECT=1的时候按下其他键//////*********************************************
if(se==1)
{
/////////////////////TRIANGLE 三角
if (Psx.digital_buttons == psxTri && TRIANGLE==0)
{
TRIANGLE=1;
Serial.println("Select + pressed_TRIANGLE"); //按下三角
}
if (Psx.digital_buttons != psxTri && TRIANGLE==1)
{
TRIANGLE=0;
Serial.println("Select + released_Trlangle"); //松开 三角
}
if (Psx.digital_buttons == psxTri)
{
Serial.println("Select + Down_TRIANGLE"); //一直按住三角
}
/////////////////////CROSS 叉叉
if (Psx.digital_buttons == psxX && CROSS==0)
{
CROSS=1;
Serial.println("Select + pressed_CROSS"); //按一次叉叉
}
if (Psx.digital_buttons != psxX && CROSS==1)
{
CROSS=0;
Serial.println("Select + released_CROSS"); //松开 叉叉
}
if (Psx.digital_buttons == psxX )
{
Serial.println("Select + Down_CROSS"); //一直按住叉叉
}
/////////////////////SQUARE 方框
if (Psx.digital_buttons == psxSqu && SQUARE==0) //按下方框
{
SQUARE=1;
Serial.println("Select + pressed_SQUARE"); //发送按下方框
}
if (Psx.digital_buttons != psxSqu && SQUARE==1) ///松开方框
{
SQUARE=0;
Serial.println("Select + released_SQUARE"); //发送 松开方框
}
if (Psx.digital_buttons == psxSqu) ////按住方框
{
Serial.println("Select + Down_SQUARE"); //发送按住方框
}
/////////////////////CIRCLE 圈圈
if (Psx.digital_buttons == psxO && CIRCLE==0) ///一直按住圈圈
{
CIRCLE=1;
Serial.println("Select + pressed_CIRCLE"); //发送按下圈圈
}
if (Psx.digital_buttons != psxO && CIRCLE==1) ///松开圈圈
{
CIRCLE=0;
Serial.println("Select + released_CIRCLE"); //发送 松开圈圈
}
if (Psx.digital_buttons == psxO) ///一直按住圈圈
{
Serial.println("Select + Down_CIRCLE"); //发送一直按住圈圈
}
////////////////L1
if (Psx.digital_buttons == psxL1 && L1==0) /////按下L1
{
L1=1;//取反
Serial.println("Select + pressed_L1");
}
if (Psx.digital_buttons != psxL1 && L1==1) ///松开L1
{
L1=0;//取反
Serial.println("Select + released_L1"); //发送 松开L1
}
if (Psx.digital_buttons == psxL1) ////////一直按住L1
{
Serial.println("Select + Down_L1");
}
////////////////////R1
if (Psx.digital_buttons == psxR1 && R1==0) //按下R1
{
R1=1;//取反
Serial.println("Select + pressed_R1");
}
if (Psx.digital_buttons != psxR1 && R1==1) ///松开L1
{
R1=0;//取反
Serial.println("Select + released_R1"); //发送 松开L1
}
if (Psx.digital_buttons == psxR1)
{
Serial.println("Select + Down_R1");
}
}
//////////////////*************************************************////////////////////
////////////////L2
if (Psx.digital_buttons & psxL2 && L2==0)
{
L2=1;
Serial.println("pressed_L2");
t=t+100;
if (t>=2000)
{
t=2000;
}
Serial.print("T=");Serial.println(t);
p=p-5;
if(p<=5)
{
p=5;
}
Serial.print("P=");Serial.println(p);
}
if (Psx.digital_buttons==0 && L2==1) ///松开L1
{
L2=0;//取反
Serial.println("released_L2"); //发送 松开L1
}
if (Psx.digital_buttons & psxL2)
{
Serial.println("Down_L2");
}
///////////////////////R2
if (Psx.digital_buttons & psxR2 && R2==0) //按下R2
{
R2=1;
Serial.println("pressed_R2"); //
t=t-100;
if (t<100)
{
t=100;
}
Serial.print("T=");Serial.println(t);
p=p+5;
if(p>=50)
{
p=50;
}
Serial.print("P=");Serial.println(p);
}
if (Psx.digital_buttons==0 && R2==1) ///松开L1
{
R2=0;//取反
Serial.println("released_R2"); //发送 松开L1
}
if (Psx.digital_buttons & psxR2)
{
Serial.println("Down_R2");
}
////////////////JoyL 左摇杆按键
if (Psx.digital_buttons & psxJoyL && JoyL==0) ///按下左摇杆
{
JoyL=1;
Serial.println("pressed_JoyL"); //发送按下左摇杆
c1=c1++;
c1_1=c1%2; //求余数 的奇偶性
if(c1_1==0)
{
// 左摇杆x1 y1使能
}
if(c1_1==1)
{
Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy);//左右 头部舵机
Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy);//前后 左手指舵机
//左摇杆 x1 y1 不使能
}
}
if (Psx.digital_buttons==0 && JoyL==1) ///松开L1
{
JoyL=0;//取反
Serial.println("released_JoyL"); //发送 松开L1
}
///////////////////////JoyR 右摇杆按键
if (Psx.digital_buttons & psxJoyR && JoyR==0) ///按下 右摇杆
{
JoyR=1;
Serial.println("pressed_JoyR"); // //发送按下右摇杆
c2=c2++;
c2_1=c2%2; //求余数 的奇偶性
if(c2_1==0)
{
// 右摇杆x2 y2使能
}
if(c2_1==1)
{
Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);//左右
Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);//前后 右手指舵机
//右摇杆 x2 y2 不使能
}
}
if (Psx.digital_buttons==0 && JoyR==1) ///松开右摇杆
{
JoyR=0;//取反
Serial.println("released_JoyR"); //发送 松开右摇杆
}
///////////////////摇杆////////////************************************///////////
if (Psx.Controller_mode==0x0073) /////如果是模拟模式 才开启摇杆
{
int x1 = Psx.Left_x; // x= 0-128-255
int y1 = Psx.Left_y; //y= 0-127-255
int x2 = Psx.Right_x;
int y2 = Psx.Right_y;
int x=128;int y=127;//XY的中间数值,新手柄适用
//将模式数值0-255 转换成P值 500-2500
///x1
if (x1<=x)
{
X1=500+x1*7.8125;
}
if (x1>x)
{
X1=500+(x1+1)*7.8125;
}
///y1
if (y1<y)
{
Y1=500+(y1)*7.8125;
}
if (y1>=y)
{
Y1=500+(y1+1)*7.8125;
}
///X2
if (x2<=x)
{
X2=500+x2*7.8125;
}
if (x2>x)
{
X2=500+(x2+1)*7.8125;
}
///y2
if (y2<y)
{
Y2=500+y2*7.8125;
}
if (y2>=y)
{
Y2=500+(y2+1)*7.8125;
}
if(c1_1==0)
{
///////////////LEFT_X
if (x1<118||x1>138)
{
Serial.print("analog left x= "); Serial.println( x1);
Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy);
b=1;
}
if (x1>118 && x1<138&& b==1)
{
Serial.print("analog left x= "); Serial.println( x1);
Serial.print("#10P"); Serial.print(X1);Serial.print("S");Serial.println(s_1);delay(dy);
b=0;
}
///////////// LEFT_Y
if (y1<117||y1>137)
{
Serial.print("analog left y= "); Serial.println( y1);
Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy);
b1=1;
}
if (y1>117 && y1<137&& b1==1)
{
Serial.print("analog left y= "); Serial.println( y1);
Serial.print("#11P"); Serial.print(Y1);Serial.print("S");Serial.println(s_1);delay(dy);
b1=0;
}
}
if(c2_1==0)
{
///////////////RIGHT_X
if (x2<118||x2>138)
{
Serial.print("analog right x= "); Serial.println( x2);
Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);
b2=1;
}
if (x2>118 && x2<138&& b2==1)
{
Serial.print("analog right x= "); Serial.println( x2);
Serial.print("#4P"); Serial.print(X2);Serial.print("S");Serial.println(s_1);delay(dy);
b2=0;
}
///////////// RIGHT_Y
if (y2<117||y2>137)
{
Serial.print("analog right y= "); Serial.println( y2);
Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);
b3=1;
}
if (y2>117 && y2<137&& b3==1)
{
Serial.print("analog right y= "); Serial.println( y2);
Serial.print("#13P"); Serial.print(Y2);Serial.print("S");Serial.println(s_1);delay(dy);
b3=0;
}
}
}
}
Comments