一、智能车舵机控制

article/2025/8/18 18:17:16

前言:
本文章主要是近期有关舵机知识的总结,将分别从舵机的控制原理,控制流程和代码实现流程几个方面作简要介绍,由于时间紧急,难免有疏漏错误之处,欢迎留言指正
一、舵机的控制原理:
我们本次智能车使用的舵机是通过PWM进行控制。而PWM几个重要的参数就是最大值,最小值和占空比。其中占空比决定了舵机的旋转角度,如下图所示:在这里插入图片描述
不同的占空比控制不同的角度。而我们的目的就是通过摄像头和电感采集上来的数据(MiddleLine)通过算法来控制占空比(脉冲宽度),进而控制舵机的旋转角度。简单介绍了原理之后下面就开始介绍舵机的使用和控制。
二、舵机左右极值和中值参数设置:
使用舵机的第一步就是先对舵机进行调中,目的是使舵机左右自由度相同,从而是控制更加准确和方便,如果不调中,很容易出现舵机打死现象,轻则是车子无法正常转弯,重则烧坏舵机。调中方法:
1、调左极值:
使以下单个参数相同,观察舵机旋转角度,当左轮即将接触车子为最佳。
2、调中值:
方法同上。
3、调右极值:
方法同上。

位置:macro.h

//-------舵机pwm-------------------
#define STEER_MIN 9580  //左值9455
#define STEER_MID 9580 //中值9500
#define STEER_MAX 9580 //又值9580

注意:在调中的过程中,应尽量做到左右对称,如果左右不对称,可以采取以下几种方法:
(1)、调节舵机中值角度位置,尽量做到左右自由度对称
(2)、调节连接杆位置(推荐)
(3)、有的时候由于工艺的限制,会有部分偏差,只能通过其他硬件结构和软件设计进行弥补
二、哪里用到这些值:
1、角度控制
位置:control.c

void AngleControl(PID *pid_steer)
{float middle_line = getMiddleLine();if(middle_line > IMAGE_WIDTH)//中线偏差限幅middle_line = IMAGE_WIDTH;else if(middle_line < 0)middle_line = 0;
#if DIR == 0//左小右大steer_u = STEER_MID - PositionalPD(pid_steer, middle_line);
#elif DIR == 1steer_u = STEER_MID + PositionalPD(pid_steer, middle_line);
#endif//舵机脉宽平滑变化if(steer_u > STEER_MAX)steer_u = STEER_MAX;else if(steer_u < STEER_MIN)steer_u = STEER_MIN;setPWMWidth(steer_u);
}uint8 cnt = 0;
uint8 flag = 0;

从这段代码可以看出,程序先通过函数getMiddleLine()获得中线,然后对中线进行了限幅,防止数值过大或过小损坏硬件。然后传递到 PositionalPD()函数,该函数通过中线和PID结构体中的数值进行计算,最终得出一个误差数值(PD运算得出)output,然后与舵机中值做差,数值传给steer_u ,然后再函数setPWMWidth()函数中对steer_u做一次限幅,然后传递给函数cmt_pwm_duty()就可以进行PWM的设置了,下面将对相关函数作简要介绍:
(1)、脉冲宽度设置:

void setPWMWidth(uint16 steer_u)
{if(steer_u > STEER_MAX) {steer_u = STEER_MAX;} else if(steer_u < STEER_MIN) {steer_u = STEER_MIN;}cmt_pwm_duty(steer_u/10); 
}

该函数看似是进行脉冲宽度设置,实质时进行限幅作用,真正进行脉宽设置的是cmt_pwm_duty()函数。
(2)、cmt_pwm_duty()函数:

void cmt_pwm_duty(uint16 duty)
{uint32 temp_high_num, temp_low_num;//计算高低电平的计数次数temp_low_num = (cmt_period*(CMT_PRECISON-duty)/CMT_PRECISON);temp_high_num = (cmt_period*(duty)/CMT_PRECISON);//设置低电平时间temp_low_num--;CMT->CMD1 = temp_low_num >> 8;CMT->CMD2 = (uint8)temp_low_num;//设置高电平时间CMT->CMD3 = temp_high_num >> 8;CMT->CMD4 = (uint8)temp_high_num;}```
这里面有几个参数需要大家了解一下:
1、cmt_period :一个周期计数的次数表达式:cmt_period = temp_clk/(temp_div+1)/freq;注意:这里用到了预分频的方法,就不多做介绍2、CMT_PRECISON:占空比精度
3、duty:占空比

该函数的作用是进行占空比设置,用到了CMT模块,这里不做详细介绍。

(3)、PositionalPD()函数:


//积分饱和,输出限幅
int16 PositionalPD(PID *pid, float sensor_val)//位置式pd
{float output = 0.0f;float error = 0.0f;float p_error = 0.0f;//当前误差项float d_error = 0.0f;//微分误差项error = pid->set_point - sensor_val;p_error	= error;d_error = error - pid->last_error;if(fabs(error) < 0.1f)output = 0.0f;elseoutput = pid->K_p * p_error + pid->K_d * d_error;pid->last_error = error;return (int)output;
}

该函数的功能主要是根据摄像头和电感传回来的数据进行误差计算,用到了PID控制,算法不是很难,不做详细介绍。
4、 getMiddleLine()函数:

float getMiddleLine(void)
{float inductor = getInductorMiddleLine();float camera = getCameraMiddleLine();
#if CAMERA==1float result = inductor * car_info.K_g + camera * (1 - car_info.K_g);
#elsefloat result = inductor;
#endifcar_info.mid_line_ = result;return result;
}

该函数的作用是获得中线,当有摄像头时取摄像头和电感的加权值,否则使用电感的数值,这也是为什么不用摄像头也能进行循迹的原因。
三、总结:
由次可以看出,舵机控制大致分以下几个步骤:
1、调中,就是调那三个数值
2、获得中线:getMiddleLine(),分两种情况,有摄像头和无摄像头
3、将获得的中线值和调中设置的值通过函数PositionalPD()PID运算得出差值,并将结果传给steer_u
4、根据steer_u的数值,通过函数setPWMWidth()进行限幅
5、限幅后将数值steer_u/10传给函数cmt_pwm_duty()进行脉宽设置
以上就是舵机的大致控制流程,由于能力有限,难免有疏漏错误之处,欢迎留言指正,进行交流。由于本次主要是介绍舵机的有关控制,里面有很多细节没有做详细介绍,大家可以自己上网查阅相关资料进行了解。比赛是一个学习的过程,只有多动手,勤思考,才能有所收获,失败的经验比成功地经验更重要。


http://chatgpt.dhexx.cn/article/ThOF3AIe.shtml

相关文章

单片机PWM舵机控制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、PWM是什么&#xff1f;二、如何控制舵机&#xff1f; 一、PWM是什么&#xff1f; PWM&#xff0c;英文名Pulse Width Modulation&#xff0c;是脉冲宽度调制缩…

快速学习Stm32舵机控制板控制多个舵机运动以及调速

本次分享stm32对多个舵机的控制&#xff0c;之前讲解过单个舵机的控制。以及控制原理&#xff0c;定时器的使用和pwm的输出来控制一个舵机的角度转向。这次就和大家分享一下多个舵机的控制以及调速。利用单片机实现对 8 个舵机的同时控制&#xff0c;掌握多个舵机控制程序实现方…

51单片机舵机控制

51单片机舵机控制系统 概述硬件设计程序设计PWM波的产生矩阵按键功能与数码管显示参数传递完整程序 外加模块 概述 在这篇博客中&#xff0c;将介绍一个基于51单片机的舵机控制系统&#xff0c;其可以通过矩阵按键输入角度&#xff0c;舵机打到预定角度&#xff0c;并在数码管…

Arduino基础入门篇28—舵机控制

舵机是一种位置「角度」伺服的驱动器&#xff0c;适用于那些需要角度不断变化并可以保持的控制系统。目前在高档遥控玩具、航模、机器人中已经得到普遍使用。舵机是一种俗称&#xff0c;其实是一种伺服马达。本篇通过官方驱动库来实现舵机控制。 1. 舵机介绍 结构组成 舵机实…

OpenMV输出PWM,实现对舵机控制

OpenMV的定时器官方函数介绍&#xff1a;Timer类 – 控制内部定时器 目录 OpenMV的PWM资源介绍 为什么要用OpenMV输出PWM OpenMV的PWM资源分配 资源 注意 建议 PWM输出代码 代码讲解 Timer Timer.channel tim.channel与Timer.channel区别 Timer.channel解析 OpenM…

舵机控制原理及常见问题

舵机控制 工作电压&#xff1a;3.5V/4,2V/4.8V —— 6V/6.8V/7.2V/8.4V(看具体型号参数) 切记&#xff1a;舵机不要接在电脑USB上调试&#xff0c;舵机启动瞬间大电流&#xff08;10-24倍工作电流&#xff09;可能会导致电脑死机 注意事项&#xff1a;PWM波形正确时&#xf…

第9章 舵机控制

有一种电机可以在程序的控制下&#xff0c;在一定范围内连续改变输出轴角度并且可以保持住。这种电机最早被用在航模和船模等遥控模型中&#xff0c;控制各种舵面的转动&#xff0c;这就是舵机。现在舵机除了运用在 遥控模型中&#xff0c;也大量的运用在各种机器人、机械臂的关…

Arduino入门001 - 舵机控制

Arduio基础入门篇001 - 舵机控制 一、舵机介绍 1&#xff0c;结构组成 一般来讲舵机主要由以下几个部分组成&#xff0c;舵盘、减速齿轮组、位置反馈电位计、直流电机、控制电路等。舵机的输入线共有三条&#xff0c;如图1所示&#xff0c;红色中间&#xff0c;是电源线&…

舵机控制(STM32F103C8T6)

前言 本文是以STM32F103C8T6作为主控芯片&#xff0c;通过PB6端口输出PWM&#xff0c;实现控制180舵机。 一、舵机控制原理 &#xff08;一&#xff09;概述 舵机是一种位置伺服驱动器器&#xff0c;是一种带有输出轴的小装置。当我们向伺服器发送一个控制信号时&#xff0c;…

Java 源代码怎么执行的

许多 Java 虚拟机的执行引擎在执行 Java 代码的时候都是解释执行&#xff08;通过解释器执行&#xff09;和编译执行&#xff08;通过即时编译器产生本地代码执行&#xff09;混合运行。 大体流程为&#xff1a; 编写 java 文件源码通过 javac 编译器将 java 源码编译为字节码流…

Java基础-java程序代码截取字符串及判断字符串是否包含某个字符(串)

文章目录 有一串字符串&#xff0c;是一串拼接码&#xff0c;如何截取获取想要的字段&#xff1f;判断字符串是否包含某个字符&#xff08;串&#xff09;indexOf方法 有一串字符串&#xff0c;是一串拼接码&#xff0c;如何截取获取想要的字段&#xff1f; public class Inte…

编写高质量JAVA程序代码的建议

--------------------------------------------------------------------------------------------------- 前言&#xff1a;原著《改善JAVA程序的151个建议》有151个建议&#xff0c;我在拜读的过程根据自己的理解合并了其中的几个&#xff0c;并将每个建议的核心要义进行了一…

java简单记事本代码_简单记事本的java程序代码

展开全部 天啊&#xff0c; 冖_Na0 为什么会有62616964757a686964616fe4b893e5b19e31333262343038我编的记事本代码呢&#xff1f;&#xff1f;&#xff1f;呵呵……你肯定是“请教”过我的吧&#xff1f;&#xff1f; 呵呵……我自己编了一个&#xff0c;不过呢&#xff0c;没…

IntelliJ IDEA 写java程序代码

快捷键 注释 单行&#xff1a;选中代码 ctrl/ 再来一次就是取消 多行&#xff1a;选中代码 ctrlshift/ 再来一次就是取消 格式化 CtrlAltL

Android studio如何运行java程序代码

先看Java程序类 public class GGG {public static void main(String[] args) {System.out.println("我是java程序");} }就是这么简单的一个java程序&#xff0c;在之前studio上可以直接运行&#xff0c;但是像现在升级studio后就发现运行报错&#xff1a; 首先java…

怎样使用lntelliJ IDEA 编写Java程序代码?

下面使用IDEA创建一个Java程序&#xff0c;实现在控制台上打印HelloWorld!的功能&#xff0c;具体步骤如下。 1.创建Java项目 进入New Project界面后&#xff0c;单击New Project选项按钮创建新项目&#xff0c;弹出New Project对话框&#xff0c;如下图所示。 New Projeet 对…

Java学习代码合集

其实我学习java最根本的原因是&#xff1a;我是一个挺关注外在的人&#xff0c;虽然是个程序员&#xff0c;所以我很喜欢写出那些带有漂亮的界面的程序&#xff0c;因为C总是控制台&#xff0c;我不是很喜欢&#xff0c;在这份java代码合集中&#xff0c;我会记录自己学习Java界…

Java开发常用代码

一.获取UUID UUID uuid UUID.randomUUID(); String str uuid.toString(); // 去掉“-” String s str.replaceAll("-", "");二.获取固定格式的时间字符串 第一种 //获取当前时间对象 Date d new Date(); //创建日期格式化类对象,”yyyy/MM/dd HH:mm…

一个简单的Java例程

编写一个程序&#xff0c;输出如下&#xff1a; 1.在IDEA中新建一个helloworld类&#xff0c;注意Java中严格区分大小写 2.在文件中添加如下代码&#xff1a; 源代码如下&#xff1a; public class helloworld{public static void main(String[] args){System.out.println(&q…

Python3读取大文件的方法

Python3读取大文件的方法 1. 方法一&#xff1a;利用yield生成器2. 方法二&#xff1a;利用open()自带方法生成迭代对象&#xff0c;这个是一行一行的读取3. 二者的比较 1. 方法一&#xff1a;利用yield生成器 def readPart(filePath, size1024, encoding"utf-8"):w…