实物展示
1、选材用料
2、设计原理
2、代码展示
#include <PS2X_lib.h>
#include<AFMotor.h>
#define PS2_DAT 13 //14 //对应的串口初始化,arduino板上的引脚分别连接PS2上对应的标识引脚
#define PS2_CMD 11 //15 //引脚可按自己连接更改
#define PS2_SEL 10 //16
#define PS2_CLK 12 //17
AF_DCMotor motor1(1);//对四个电机的连接建立
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
#define pressures true
#define rumble true
PS2X ps2x; // create PS2 Controller Class
int error = 0;//以防出错的检测
byte type = 0;
byte vibrate = 0;
void (* resetFunc) (void) = 0;
/*检测连接是否建立,在无显示屏,无法print情况下无用*/
void setup(){
Serial.begin(115200);//串口通讯波特率的建立
motor1.setSpeed(200); //四个电机速度的设置(200可按实际需要速度更改)
motor2.setSpeed(200);
motor3.setSpeed(200);
motor4.setSpeed(200);
delay(500); //added delay to give wireless ps2 module some time to startup, before configuring it
error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
if(error == 0){
Serial.print("Found Controller, configured successful ");
Serial.print("pressures = ");
if (pressures)
Serial.println("true ");
else
Serial.println("false");
Serial.print("rumble = ");
if (rumble)
Serial.println("true)");
else
Serial.println("false");
Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
Serial.println("holding L1 or R1 will print out the analog stick values.");
Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
}
else if(error == 1)
Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
else if(error == 2)
Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
else if(error == 3)
Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
type = ps2x.readType();
switch(type) {
case 0:
Serial.println("Unknown Controller type found ");
break;
case 1:
Serial.println("DualShock Controller found ");
break;
case 2:
Serial.println("GuitarHero Controller found ");
break;
case 3:
Serial.println("Wireless Sony DualShock Controller found ");
break;
}
}
/*前后左右函数*/
void STOP(){
motor1.run(RELEASE);
motor2.run(RELEASE);
motor3.run(RELEASE);
motor4.run(RELEASE);
}//停止函数
void RUN(){
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}//可调速的前进函数
void LEFT(){
motor1.run(FORWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(FORWARD);
}//可调速的左转函数
void RIGHT(){
motor1.run(BACKWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(BACKWARD);
}//可调速的右转函数
void BACK(){
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
}//可调速的后退函数
void zishun(){
motor1.run(FORWARD);
motor2.run(BACKWARD);
motor3.run(FORWARD);
motor4.run(BACKWARD);
}//顺时针自转
void zini(){
motor1.run(BACKWARD);
motor2.run(FORWARD);
motor3.run(BACKWARD);
motor4.run(FORWARD);
}//逆时针自转
/*直接引用示例库,在按下某一按键后,会print 提示,
在提示后加入需要运行的代码,即可实现需要效果,也
可删去多余部分,在此小编直接引用*/
void loop() {
if(error == 1){ //skip loop if no controller found
resetFunc();
}
if(type == 2){ //Guitar Hero Controller
ps2x.read_gamepad(); //read controller
if(ps2x.ButtonPressed(GREEN_FRET))
Serial.println("Green Fret Pressed");
if(ps2x.ButtonPressed(RED_FRET))
Serial.println("Red Fret Pressed");
if(ps2x.ButtonPressed(YELLOW_FRET))
Serial.println("Yellow Fret Pressed");
if(ps2x.ButtonPressed(BLUE_FRET))
Serial.println("Blue Fret Pressed");
if(ps2x.ButtonPressed(ORANGE_FRET))
Serial.println("Orange Fret Pressed");
if(ps2x.ButtonPressed(STAR_POWER))
Serial.println("Star Power Command");
if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed
Serial.println("Up Strum");
if(ps2x.Button(DOWN_STRUM))
Serial.println("DOWN Strum");
if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed
Serial.println("Start is being held");
if(ps2x.Button(PSB_SELECT))
Serial.println("Select is being held");
if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE
Serial.print("Wammy Bar Position:");
Serial.println(ps2x.Analog(WHAMMY_BAR), DEC);
}
}
else { //DualShock Controller
ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed
if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed
Serial.println("Start is being held");
if(ps2x.Button(PSB_SELECT))
Serial.println("Select is being held");
if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed
Serial.print("Up held this hard: ");
RUN();//按压PSB_PAD_UP键后执行RUN()函数
Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
}
if(ps2x.Button(PSB_PAD_RIGHT)){
Serial.print("Right held this hard: ");
RIGHT();//按压PSB_PAD_RIGHT键后执行 RIGHT()函数右转
Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
}
if(ps2x.Button(PSB_PAD_LEFT)){
Serial.print("LEFT held this hard: ");
LEFT();//按压PSB_PAD_LEFTT键后执行LEFT()函数左转
Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
}
if(ps2x.Button(PSB_PAD_DOWN)){
Serial.print("DOWN held this hard: ");
BACK();//按压PSB_PAD_DOWN键后执行 BACK()函数后退
Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
}
if(ps2x.Button(PSB_R3)){
Serial.print("DOWN held this hard: ");
zishun();//按压PSB_R3键后执行zishun()函数顺时针自转
Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
}
if(ps2x.Button(PSB_L3)){
Serial.print("DOWN held this hard: ");
zini();//按压PSB_L3键后执行 zini()函数逆时针自转
Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
}
/*以下函数在实作中没有用到*/
vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button
if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on)
if(ps2x.Button(PSB_L3))
Serial.println("L3 pressed");
if(ps2x.Button(PSB_R3))
Serial.println("R3 pressed");
if(ps2x.Button(PSB_L2))
Serial.println("L2 pressed");
if(ps2x.Button(PSB_R2))
Serial.println("R2 pressed");
if(ps2x.Button(PSB_TRIANGLE))
Serial.println("Triangle pressed");
STOP();
}
if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed
Serial.println("Circle just pressed");
if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released
Serial.println("X just changed");
if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released
Serial.println("Square just released");
if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE
Serial.print("Stick Values:");
Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX
Serial.print(",");
Serial.print(ps2x.Analog(PSS_LX), DEC);
Serial.print(",");
Serial.print(ps2x.Analog(PSS_RY), DEC);
Serial.print(",");
Serial.println(ps2x.Analog(PSS_RX), DEC);
}
}
delay(50);
}
3、结构原理
3.1建模
通过建模模拟车体基本构架,便于结构设计、无实物展示展示和组装;
- (b)
图3.1 小车sw模型
小车简介:小车将采用钢质小车地盘作为车身;以直流减速电机提供动力;麦克纳姆轮作为车轮;采取可装卸推球凹槽。
- (b)
图3.2 小球推槽结构
小球推槽结构简介:采用螺母结构固定于车身,竞速赛道时取下提高速度和可操控性,凹槽采取两段圆弧结构,大圆弧加宽凹槽宽度,使小车在遥控行驶的过程中更易捕获小球,凹槽中的小圆弧用于在推动小球时限制小球的较大范围运动,使在推小球到指定区域外时,小车减速,小球依靠惯性运动进入区域时,对小球的运动角度把握的更精准。
3.2 麦克纳姆轮原理
3.2.1 物理原理
3.2.1.1两种轮
对于四轮小车来说,一套麦克纳姆轮至少应含有两种不同的轮子,民间叫法有很多,百度上将他们称为:“麦克纳姆轮左和麦克纳姆轮右”,下面简称左轮和右轮;
左轮:正转可以向左前方运动,反转向右后方的轮(注意是运动方向,与给地面摩擦力的方向相反)
右轮:正转向右前方运动,反转向左后方的轮
当主轮转动时会带动周边轮的转动,而周边轮与主轮的转动成一定角度,所以可以产生一个斜向的力。因此多个麦轮组合使用、分别控制就可以使小车在主轮方向不变的情况下实现全向移动了(如果一时没想清楚就请继续看下面对各个运动状态的分析)。
对于左右轮旋转会产生什么方向的力是关键,你可以尝试着进行受力分析,这里就没必要讲解了,只需要大脑里稍微想象应该一下就明白了(或者直接记上面的结论也是一样的)
核心就是利用安装的对称性抵消不需要的力,叠加目标速度方向的力。
3.2.1.2一种可行的安装方式
对于四轮小车来说;一般来说的安装方式是:
图为一辆麦轮小车的俯视图,其中左前方和右后方的轮为左轮,其余两个为右轮
3.2.2 控制原理
3.2.2.1 前进/后退
以上述方式安装的麦轮同时正转时,前部两个轮与后方两个轮的侧方的力都可以抵消,只剩下向前方的力。小车就可以向前运动
图为,向前时横向移动的力。
后退反转即可,分析同理。
3.2.2.2 左右平移
原理是将小车同一侧的两个麦轮以相反的方向旋转,这样沿前后方的力就会抵消,而横向的力有恰好是同一方向。
例如向左移动就所有右轮全反转,左轮全正转。
3.2.2.3 自旋
原理就是一侧的轮子向后,另一侧的轮子向前;这样对于同一侧的两个轮子来说,横向的力还是可以抵消
如左侧两个轮子正转,右侧两个轮子反转就可以使小车顺势针旋转,反之则逆时针。
以上这几种运动方式需要注意的是,四个轮子虽然转的方向不同,但是转速需要严格相同,不然运动就不再准确。
3.3 控制逻辑
通过一套完备的代码,保证小车运行的速度和灵活性,通过手柄按键,控制实现前后左右、原地掉头,45°斜向的移动。
图3.3.1 PS2手柄按键示意图
图3.3.2连接示意图
(a)初始化设置
- 部分行进函数
图3.3.3 部分代码展示
代码简介:对arduino于PS2手柄连接Pin口进行初始话设置;如用L298n,则对控制L298n的IO口进行设置,将前后左右、原地掉头,45°斜向的移动封装为函数,当接收到PS2手柄的通讯信息时,按照不同按键的信息进行调用,实现移动。
3.4 组装
根据建模结果,由钢制车架(亚克力板)、直流电机、小轮胎、电池盒、电池等搭建小车,连接arduino板与推动足球的3D打印支架
文章来源:https://www.toymoban.com/news/detail-780925.html
图3.3.4 目前完成部分图文章来源地址https://www.toymoban.com/news/detail-780925.html
到了这里,关于基于arduino及PS2的麦克纳姆轮遥控小车的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!