概述
程序摘要
@RequestMapping(value = "/opt" , method = RequestMethod.POST)
String moveType(@RequestParam(value = "speed") int speed,@RequestParam(value = "opt") String opt) {
logger.info("{},速度为:{}",MoveTypeEnum.forward.getOptName(),speed);
new Thread(){
@Override
public void run(){
Car.opt_type(speed,opt);//小车运动
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
return "运动...";
}
试验目标:
1.针对自主研发麦克纳姆轮,配合小车底盘,编写对应Java程序
2.提供一个java springboot的项目,打包好以后,放到树莓派中,运行,项目提供出restful风格的接口,对小车进行远程控制。
3.通过远程接口。控制小车的前进,后退,直接左向运动,直接右方向运动。
这样做,是为了后面通过集群化的方式进行处理打下基础。
定义与范围划分:
1.载体:小车底盘,轮子等非电子类物品统称为载体。
2.控制中心:树莓派称为控制中心
3.电子部件: 42步进电机,TB6600电机驱动,电源,电线等称为电子设备,驱动又称为芯片,
4.软件部分:java语言与其操作系统划分为软件部分
========================================================================
一.准备
思路:通过java web程序,通过接口的方式,控制小车的前进,停止前进功能。由于小车的轮子比较特殊,用的是麦克纳姆轮,所以可以做到直接右直行,左直行等。本文程序只有一个方向的行进,为了方便测试,提供停止运动接口。
1.控制中心
树莓派4b(对树莓派的使用不熟悉或者对java不熟悉的同学请关注专栏,可以提供一些指导)
代码编写与管理平台(方便网页控制)
2.电子设备
电机驱动TB6600*2
42步进电机 *4
电源盒(24v电源变压器或者12v电池,不能用1.5v,电压不够)
电源线若干
3.软件与程序
centos7 32位
java的运行编译环境jdk8
其中包括控制小车运动轨迹的pid算法
4.载体
麦克纳姆轮两左两右共四个
小车底盘
------------------------------------------------------------------------------------------------------------------------------------------------------------------
二.电路连接示意图
2.树莓派引脚示意图,GPIO与物理位序的映射
2.树莓派与TB6600连接图
3.物理图
具体链接线使用了中转连接头的方式。详情请留言
4.电源
电源使用了与之前控制单个电机的方式是一样的。
5.TB6600配置
参考控制单个电机的 树莓派通过TB6600控制单个步进电机
-----------------------------------------------------------------------------------
三.程序部分
项目地址:https://github.com/jiaozg22/global-fairy-top-pi4j.git
项目框架: spring boot
中 间 件: maven,git,pi4j,wiringpi.需要在树莓派上提前安装并配置成功,才能部署运行
测试工具: jmeter
为了详细讲解代码部分,将项目进行拆分为以下几部分:pom文件,接口,核心类文件,测试文件
1.pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>top.fairy.global</groupId>
<artifactId>global-fairy-top-pi4j</artifactId>
<version>0.0.1-SNAPSHOT</version>
<url>https://www.pi4j.com</url>
<name>global-fairy-top-pi4j</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.version>1.2</project.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/com.pi4j/pi4j-core -->
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.pi4j/pi4j-device -->
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-device</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.pi4j/pi4j-gpio-extension -->
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-gpio-extension</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8081</port>
<path>/</path>
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.接口文件
package top.fairy.global.globalfairytoppi4j.action;
import com.pi4j.io.gpio.*;
import com.pi4j.util.CommandArgumentParser;
import com.pi4j.util.ConsoleColor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.fairy.global.globalfairytoppi4j.basic.Car;
import top.fairy.global.globalfairytoppi4j.basic.ControlCenter;
import top.fairy.global.globalfairytoppi4j.basic.MoveTypeEnum;
import top.fairy.global.globalfairytoppi4j.utils.GpioUtil;
/**
* @author jiao_zg22
* @version 1.0
* @description 接口
* @date 2020/12/4 23:11
*/
@RestController
@SpringBootApplication
@RequestMapping(value = "/driver")
public class DriverControllor {
private static final Logger logger = LogManager.getLogger();
//这里使用@RequestMapping注解表示该方法对应的二级上下文路径
@RequestMapping(value = "/startPi", method = RequestMethod.GET)
String getUserByGet(@RequestParam(value = "userName") String userName) {
logger.info("startPi");
//检查启动的各种状态
String result= "";
// ControlCenter.linkToMotor();
return result;
}
//这里使用@RequestMapping注解表示该方法对应的二级上下文路径
@RequestMapping(value = "/opt" , method = RequestMethod.POST)
String moveType(@RequestParam(value = "speed") int speed,@RequestParam(value = "opt") String opt) {
logger.info("{},速度为:{}",MoveTypeEnum.forward.getOptName(),speed);
new Thread(){
@Override
public void run(){
Car.opt_type(speed,opt);//小车运动
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
return "运动...";
}
//这里使用@RequestMapping注解表示该方法对应的二级上下文路径
@RequestMapping(value = "/stop" , method = RequestMethod.GET)
String stop(@RequestParam(value = "stop") String stop) {
logger.info("操作:stop");
Car.stop();
return "运动...";
}
}
3.核心类
package top.fairy.global.globalfairytoppi4j.basic;
import com.pi4j.io.gpio.PinState;
import com.pi4j.wiringpi.SoftPwm;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* @author jiao_zg22
* @version 1.0
* @description 接口
* @date 2020/12/4 23:16
*/
public class Car {
private static final Logger logger = LogManager.getLogger();
private static ControlCenter controlCenter = new ControlCenter();
/**
*
* @description:运动
* @author: jiao_zg22
* @time: 2020/12/13 17:08
*/
public static void opt_type(int speed,String optKey){
com.pi4j.wiringpi.Gpio.wiringPiSetup();
if(MoveTypeEnum.forward.getOptKey().equals(optKey)){
// create soft-pwm pins (min=0 ; max=100)
int setSpeedErrorNO = SoftPwm.softPwmCreate(29, 0, speed);
Long timestamp = System.currentTimeMillis();
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.LOW);
controlCenter.MS42_AL_DIR_PLUS.setState(PinState.LOW);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.LOW);
controlCenter.MS42_AR_DIR_PLUS.setState(PinState.HIGH);
// ControlCenter.MS42_AL_PUL_PLUS.setPwmRange(100);
// ControlCenter.MS42_AL_PUL_PLUS.setPwm(speed);
// continuous loop
while (true) {
for (int i = 1; i <= 6; i++) {
SoftPwm.softPwmStop(29);
SoftPwm.softPwmCreate(29, 0, speed);
SoftPwm.softPwmWrite(29, i);
SoftPwm.softPwmStop(28);
SoftPwm.softPwmCreate(28, 0, speed);
SoftPwm.softPwmWrite(28, i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timestamp = System.currentTimeMillis();
logger.info(timestamp);
}
// ControlCenter.MS42_AR_PUL_PLUS.setPwmRange(100);
// ControlCenter.MS42_AR_PUL_PLUS.setPwm(speed);
}
}else if(MoveTypeEnum.left.getOptKey().equals(optKey)){
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AL_DIR_PLUS.setState(PinState.LOW);
// ControlCenter.MS42_AL_PUL_PLUS.setPwmRange(speed);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AR_DIR_PLUS.setState(PinState.LOW);
// ControlCenter.MS42_AR_PUL_PLUS.setPwmRange(speed);
}else if(MoveTypeEnum.right.getOptKey().equals(optKey)){
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AL_DIR_PLUS.setState(PinState.LOW);
// ControlCenter.MS42_AL_PUL_PLUS.setPwmRange(speed);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AR_DIR_PLUS.setState(PinState.HIGH);
// ControlCenter.MS42_AR_PUL_PLUS.setPwmRange(speed);
}else if(MoveTypeEnum.back.getOptKey().equals(optKey)){
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AL_DIR_PLUS.setState(PinState.LOW);
// ControlCenter.MS42_AL_PUL_PLUS.setPwmRange(speed);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AR_DIR_PLUS.setState(PinState.LOW);
// ControlCenter.MS42_AR_PUL_PLUS.setPwmRange(speed);
}
logger.info("运动");
}
public static String stop() {
logger.info("操作:stop");
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.HIGH);
// ControlCenter.MS42_AL_PUL_PLUS.setShutdownOptions(true, PinState.LOW, PinPullResistance.OFF);
// ControlCenter.MS42_AR_PUL_PLUS.setShutdownOptions(true, PinState.LOW, PinPullResistance.OFF);
controlCenter.gpio.shutdown();
// controlCenter.gpio.unprovisionPin(controlCenter.MS42_AL_PUL_PLUS,controlCenter.MS42_AR_PUL_PLUS);
return "运动停止成功";
}
public static String autoMove(int speed){
controlCenter.MS42_AL_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AL_DIR_PLUS.setState(PinState.HIGH);
// controlCenter.MS42_AL_PUL_PLUS.setPwmRange(speed);
controlCenter.MS42_AR_ENA_PLUS.setState(PinState.HIGH);
controlCenter.MS42_AR_DIR_PLUS.setState(PinState.HIGH);
// controlCenter.MS42_AR_PUL_PLUS.setPwmRange(speed);
//启动自动运行处理器,进行突发事件监听,并根据情况自动调用突发事件处理程序
//TODO:JIAO_ZG22
return "自动运行中";
}
}
package top.fairy.global.globalfairytoppi4j.basic;
/**
* @author jiao_zg22
* @version 1.0
* @description 树莓派与TB6600电机的连接针脚
* 详细电路连接,请参考resources目录下的static.doc文件夹
* @date 2020/12/7 20:07
*/
public class TB6600DriverLinkPi implements LinkStrategy {
public MotorDriver driver_AL_BR = new MotorDriver();//左前,右后控制驱动
public MotorDriver driver_AR_BL = new MotorDriver();//右前,左后控制驱动
public void TB6600DriverLinkPi(){}
/**
*
* @description:生成一次连接的TB6600DriverLinkPi实例之后,后面对这次连接实例TB6600DriverLinkPi的操作,是针对相同的一组操作对象pi,chip的操作
* @author: jiao_zg22
* @time: 2020/12/8 0:02
*/
public void TB6600DriverLinkPi(MotorDriver al_br,MotorDriver ar_bl) throws Exception {
if(al_br == null || ar_bl == null){
throw new Exception("连接的芯片不能为空");
}
driver_AL_BR = al_br;
driver_AR_BL = ar_bl;
}
@Override
public void setModule(String module) {
CathodeModule cathodeModule = new CathodeModule(null);
}
@Override
public boolean link() {
ControlCenter controlCenter = new ControlCenter();
driver_AL_BR.IN_ENA_PLUS = controlCenter.MS42_AL_ENA_PLUS;
driver_AL_BR.IN_DIR_PLUS = controlCenter.MS42_AL_DIR_PLUS;
// driver_AL_BR.IN_PUL_PLUS = controlCenter.MS42_AL_PUL_PLUS;
driver_AR_BL.IN_ENA_PLUS = controlCenter.MS42_AR_ENA_PLUS;
driver_AR_BL.IN_DIR_PLUS = controlCenter.MS42_AR_DIR_PLUS;
// driver_AR_BL.IN_PUL_PLUS = controlCenter.MS42_AR_PUL_PLUS;
//TODO:jiao_zg22 判断策略
return false;
}
}
类文件比较多,需要的请到github上进行下载。如果有同学不清楚github如何使用,请关注博主专栏【编程初学者】
4.测试文件
链接:https://pan.baidu.com/s/10fpFwfoik9zx05Gy748Xsw
提取码:qujh
或者可以自己写测试接口。就是简单的post,get方式的接口
四.部署与运行
把树莓派与小车电机等组装成功以后,将代码打包成jar文件。具体的操作:
进入到开发工具如ide,运行maven,mvn clean compile package .然后找到对应的target目录下找到打包好的jar文件。
用ftp上传到树莓派/opt/software 目录下。
使用 java -jar global-fairy-top-pi4j-0.0.1-SNAPSHOT.jar 命令启动。看到端口8088启动成功。
然后通过jmeter,运行绿色的执行按钮,即可启动,如果需要停止,需要将运行接口的测试用例置位disable,将stop接口置位enable
五.测试视频
演示程序
附:由于内容较多,一篇文章篇幅有限,有需要的同学可以通过私信或者留言,对于通用性的问题会补充到文章中去。需要学习的小伙伴可以留言沟通。
最后
以上就是寒冷手链为你收集整理的树莓派通过java控制麦克纳姆轮小车程序摘要试验目标:的全部内容,希望文章能够帮你解决树莓派通过java控制麦克纳姆轮小车程序摘要试验目标:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复