四足机器人单腿算法

依据机械结构,将舵机起始位置规定于90°(其中红线所标注的即为舵机的角度极限)。经实际检测λ最小极限为0。的最小极限为0,连杆间的固定三角形中最大角为88°,图中L1,L2已知且L1=L2,各连杆间构成平行四边形。以上均为算法所需。

已知足端坐标,根据运动学逆解来推算λ,β的大小从而控制舵机转角。当

由简化图易得

,其中,经几何关系 。接下来可以推算λ,。此时可以得知小腿运动变化角度,由于λ的极限角度为0,所以最终小腿的舵机输入角度就为120°-λ。大腿运动变化角度为β,由于β最小为0,所以最终大腿舵机控制角度为50°+β。

类似的,经过同样推理,可得x<0时,

#include "PCA9685.h"
#include "math.h"
// 定义腿部参数
#define L1 10.0  // 第一个连杆的长度
#define L2 10.20  // 第二个连杆的长度
#define M_PI 3.14159265358979323846
// 逆运动学求解函数
void inverse_kinematics(float x, float y, float *theta1, float *theta2) {
	float r = sqrt(x * x + y * y);
    float theta2_2 = acos((L1*L1+L2*L2-r*r) / (2 * L2 * L1));  //角theta2
	float theta2_1 = cos((L1*L1+L2*L2-r*r) / (2 * L2 * L1));
	float theta2_0 = sqrt(1-theta2_1*theta2_1);
	float theta1_0 = fabs(atan(x/y));             //角theta1
	float arfa = (M_PI-theta2_2)/2;            	//角α
	float beita = arfa-theta1_0;
	if (x>=0){
		if((x*x+y*y)<400){
    *theta1 = fabs(beita);
    *theta2 =3*M_PI/2-theta2_2-beita-22*M_PI/45;
    // 将弧度转换为角度
    *theta1 =40+(*theta1 * 180 / M_PI);
    *theta2 =141-( *theta2 * 180 / M_PI);
		}
		else {
		PCA_MG9XX_Init(60,90);
		}
	}else if (x<0)
	{
		if((x*x+y*y)<400){
		float beita_2 =(M_PI-theta2_2)/2+theta1_0;
	*theta1 = beita_2;
    *theta2 =3*M_PI/2-theta2_2-beita_2-22*M_PI/45;
	*theta1 =40+(*theta1 * 180 / M_PI);
    *theta2 =141-( *theta2 * 180 / M_PI);
		}else {
		PCA_MG9XX_Init(60,90);
	}
}

下面是驱动PCA9685的文件

#include "PCA9685.h"

#include "math.h"
#include "stm32g4xx_hal.h"                  // Device header

#include "i2c.h"


uint8_t pca_read(uint8_t startAddress) {
    //Send address to start reading from.

    uint8_t tx[1];
    uint8_t buffer[1];
    tx[0]=startAddress;

    HAL_I2C_Master_Transmit(&hi2c2,pca_adrr, tx,1,10000);
    HAL_I2C_Master_Receive(&hi2c2,pca_adrr,buffer,1,10000);
    return buffer[0];
}

void pca_write(uint8_t startAddress, uint8_t buffer) {
    //Send address to start reading from.

    uint8_t tx[2];
    tx[0]=startAddress;
    tx[1]=buffer;
    HAL_I2C_Master_Transmit(&hi2c2,pca_adrr, tx,2,10000);

}

void pca_setfreq(float freq)//设置PWM频率

{
		uint8_t prescale,oldmode,newmode;
		double prescaleval;
		freq *= 0.92; 
		prescaleval = 25000000;
		prescaleval /= 4096;
		prescaleval /= freq;
		prescaleval -= 1;
		prescale =floor(prescaleval + 0.5f);

		oldmode = pca_read(pca_mode1);
	
		newmode = (oldmode&0x7F) | 0x10; // sleep

	
		pca_write(pca_mode1, newmode); // go to sleep

	
		pca_write(pca_pre, prescale); // set the prescaler

	
		pca_write(pca_mode1, oldmode);
		HAL_Delay(2);
	
		pca_write(pca_mode1, oldmode | 0xa1); 
}

void pca_setpwm(uint8_t num, uint32_t on, uint32_t off)
{
		pca_write(LED0_ON_L+4*num,on);
		pca_write(LED0_ON_H+4*num,on>>8);
		pca_write(LED0_OFF_L+4*num,off);
		pca_write(LED0_OFF_H+4*num,off>>8);
}
/*num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM下降计数值0~4096

一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,继续计数到off时

跳变为低电平,直到计满4096重新开始。所以当on不等于0时可作延时,当on等于0时,

off/4096的值就是PWM的占空比。*/

/*

	函数作用:初始化舵机驱动板

	参数:1.PWM频率

		  2.初始化舵机角度

*/
void PCA_MG9XX_Init(float hz,uint8_t angle)
{
	uint32_t off=0;
//	IIC_Init();

	pca_write(pca_mode1,0x0);
	pca_setfreq(hz);//设置PWM频率

	off=(uint32_t)(145+angle*2.4);
	pca_setpwm(0,0,off);pca_setpwm(1,0,off);pca_setpwm(2,0,off);pca_setpwm(3,0,off);
	pca_setpwm(4,0,off);pca_setpwm(5,0,off);pca_setpwm(6,0,off);pca_setpwm(7,0,off);
	pca_setpwm(8,0,off);pca_setpwm(9,0,off);pca_setpwm(10,0,off);pca_setpwm(11,0,off);
	pca_setpwm(12,0,off);pca_setpwm(13,0,off);pca_setpwm(14,0,off);pca_setpwm(15,0,off);
	HAL_Delay(500);
}

/*

	函数作用:控制舵机转动;

	参数:1.输出端口,可选0~15;

		  2.起始角度,可选0~180;

		  3.结束角度,可选0~180;

		  4.模式选择,0 表示函数内无延时,调用时需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;

					  1 表示函数内有延时,调用时不需要在函数后另外加延时函数,且不可调速,第五个参数可填任意值;

					  2 表示速度可调,第五个参数表示速度值;

		  5.速度,可填大于 0 的任意值,填 1 时速度最快,数值越大,速度越小;

	注意事项:模式 0和1 的速度比模式 2 的最大速度大;

*/
void PCA_MG9XX(uint8_t num,uint8_t end_angle)
{
	uint32_t off=0;
	
	off=(uint32_t)(158+end_angle*2.2);
	pca_setpwm(num,0,off);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值