舵机平滑过渡处理

之前在控制机械臂的过程当中发现舵机转动过程中运动惯量比较大,且时间并不是完全可控,所以想通过算法来实现舵机的平滑运动处理,以及对时间的精准把控。

舵机平滑过渡处理函数:

05e67a60e93e387a89b06b8acaf0d251.png

 

 f(x)取值区间:自变量和阴变量都在[0,1]之间变化,其中自变量为时间,阴变量为对应输出的CCR值,需要改变其大小只需在函数后面乘上一个比例即可。

考虑到惯性原因,模拟出来的函数其求导f(x)'在自变量为0和1的时候都为0,即代表起始时刻和终止时刻其变化率都为0;确保其平滑过渡。

robotArmControl.cpp文件

#include<robotArmControl.h>
#include"stm32f1xx_hal.h"
namespace robotArm {
typedef struct {
	float angle;
	float last_angle;
	float d_angle;
	float change_time;
	float time;
	__IO uint32_t *CCRX;
} servoData;
float ratio[5];//ArshCoke
uint8_t servo_num = 0;
servoData servo[5];

/*
 * 初始化舵机控制器
 * 可填入每个舵机的最大角度(可不同)
 */
void robot_arm_initial_ArshCoke(uint8_t servoNum, float maxAngle[]){

	servo[0].angle = 1000;
	servo[0].last_angle = 1000;
	servo[0].CCRX = (__IO uint32_t *)0;

	servo[1].angle = 1000;
	servo[1].last_angle = 1000;
	servo[1].CCRX = (__IO uint32_t *)0;

	servo[2].angle = 1000;
	servo[2].last_angle = 1000;
	servo[2].CCRX = (__IO uint32_t *)0;

	servo[3].angle = 1000;
	servo[3].last_angle = 1000;
	servo[3].CCRX = (__IO uint32_t *)0;

	servo[4].angle = 1000;
	servo[4].last_angle = 1000;
	servo[4].CCRX = (__IO uint32_t *)0;

	servo_num = servoNum - 1;
	for(int i=0;i<servoNum;i++){
		ratio[i] = 2000.0 / maxAngle[i];//要求重装载值为20000,1us计数一次
	}

}

/*
 * 设置对应编号舵机的操作寄存器
 */
void setServoChannel_ArshCoke(uint8_t num,__IO uint32_t *CCRX) {
	servo[num].CCRX = CCRX;
}


/*
 * 设置target号舵机以time ms 从当期位置转到angle
 */
void setTargetAngle_ArshCoke(float angle, float time, uint8_t target){
	angle = angle * ratio[target] + 500; //转换为比较值(目标CCRX的值)
	servo[target].last_angle = servo[target].angle;
	servo[target].angle = angle;
	servo[target].change_time = 1.0f / time; //计算时间增量
	servo[target].time = 0;
	servo[target].d_angle = angle - servo[target].last_angle;
}


/*
 * 定时器定时执行函数,用于动作实现
 * 要求此函数每隔1ms执行
 */
void actuator_ArshCoke() {
	int i;
	for(i = 0;i <= servo_num;i++){
		if(servo[i].CCRX == 0){
			break;
		}
		if (servo[i].time <= 1) {
			(*servo[i].CCRX) = (uint16_t) (((
					6 * servo[i].time * servo[i].time* servo[i].time * servo[i].time * servo[i].time
					- 15 * servo[i].time * servo[i].time * servo[i].time * servo[i].time
					+ 10 * servo[i].time * servo[i].time * servo[i].time)* servo[i].d_angle) + servo[i].last_angle);
			servo[i].time += servo[i].change_time;
		}
	}
}
}

robotArmControl.h文件:

#include"stm32f1xx_hal.h"
#ifndef ROBOTARMCONTROL_H_
#define ROBOTARMCONTROL_H_

namespace robotArm{
	void robot_arm_initial_ArshCoke(uint8_t servoNum,float maxAngle);
	void setServoChannel_ArshCoke(uint8_t num,__IO uint32_t* CCRX);
	void setTargetAngle_ArshCoke(float angle,float time,uint8_t target);
	void actuator_ArshCoke();
}



#endif /* ROBOTARMCONTROL_H_ */

注:本文仅是本人学习记录使用故没有展开说明,若有不懂的地方需要解答请留言或者联系QQ:1362501977

未经本人允许,禁止转载。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值