本文主要是介绍基于四足机器人和机械臂的运动控制系统(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 前言
- 一、四足步态
- 二、视觉抓取
- 三、远程遥控
谢绝转载,无作者许可不可用做其他用途(如教育展示产品、课程设计或毕业设计等)
前言
衔接上一篇文章,这篇文章主要来介绍项目的初步实现
一、四足步态
可以知道,该四足机器人由八个舵机组成,其中大腿四个(①②③④),小腿四个(⑤⑥⑦⑧),如下图所示:
- 第一,组装。在组装时先将每个舵机的状态调到90°,按90°状态进行组装。
- 第二,角度。你需要知道这八个舵机点位的的转动区间,比如哪个点是0°,哪个点是180°,做好记录后才能更方便的去设计。
- 第三,运动分析。其实可参考小猫的步态,通过观察发现有两种走法,一是在同一时刻有三支腿是同时踩在地上的只有一只腿提起来摆动,二是同一时刻成对角的两条腿动,两两交替行走。
我这里设计用成对角的两条腿交替运动的方法,需要注意的是在每次移动时都要将小腿提起来,再摆动大腿,然后放下小腿,这样才能控制移动到你想要的方向,具体设计如下:
- 首先初始化各点位状态。这里初始化也是有讲究的,需要根据你想要移动的幅度去设计,可以45°,可以90°等,这里我选用45°,即大腿初始化位置如下图所示,小腿初始化皆为90°。
void Init(void)
{rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL1, period, angle_90); //大腿rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL3, period, angle_135); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL4, period, angle_45); rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL1, period, angle_90); //小腿rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL3, period, angle_90); rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL4, period, angle_90);
}
- 向前迈进
rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL1, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL1, period, angle_0); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL1, period, angle_90); rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL4, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(400);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL4, period, angle_45); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL1, period, angle_45); rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL3, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL3, period, angle_90);rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL3, period, angle_90);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL2, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL2, period, angle_180); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_thread_mdelay(400);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL3, period, angle_135); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL2, period, angle_135);
- 原地转圈。让每只脚顺/逆时针移动90°,然后同时摆动大腿点位
rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL1, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL1, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL1, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL2, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL2, period, angle_180); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL3, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL3, period, angle_180); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL3, period, angle_90);rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL4, period, angle_45); rt_thread_mdelay(100);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm3_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(400);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL1, period, angle_0); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL3, period, angle_90); rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL4, period, angle_0);
二、视觉抓取
通过OpenMV摄像头去识别物块且区分颜色,利用机械臂去抓取物块并放置于不同盒子里,摄像头视角可实时在PC/iPhone显示。
- 1. 摄像头
(1) WiFi无线图传
import sensor, image, time, network, usocket, sysSSID ='Bit_Dong' # Network SSID
KEY ='1234567890' # Network key (must be 10 chars)
HOST = '' # Use first available interface
PORT = 8080 # Arbitrary non-privileged portsensor.reset()
sensor.set_framesize(sensor.QQVGA)
sensor.set_pixformat(sensor.GRAYSCALE)wlan = network.WINC(mode=network.WINC.MODE_AP)
wlan.start_ap(SSID, key=KEY, security=wlan.WEP, channel=2)def start_streaming(s):client, addr = s.accept()client.settimeout(2.0)data = client.recv(1024)client.send("HTTP/1.1 200 OK\r\n" \"Server: OpenMV\r\n" \"Content-Type: multipart/x-mixed-replace;boundary=openmv\r\n" \"Cache-Control: no-cache\r\n" \"Pragma: no-cache\r\n\r\n")clock = time.clock()while (True):clock.tick() # Track elapsed milliseconds between snapshots().frame = sensor.snapshot()cframe = frame.compressed(quality=35)header = "\r\n--openmv\r\n" \"Content-Type: image/jpeg\r\n"\"Content-Length:"+str(cframe.size())+"\r\n\r\n"client.send(header)client.send(cframe)while (True):s = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)try:s.bind([HOST, PORT])s.listen(5)s.settimeout(3)start_streaming(s)except OSError as e:s.close()
(2) 色块识别
①寻找最大色块
def find_max(blobs):max_size=0for blob in blobs:if blob[2]*blob[3] > max_size:max_blob=blobmax_size = blob[2]*blob[3]return max_blob
②颜色辨识,读取20次判断结果,取众数并传到MCU
for i in range(20):for blob in img.find_blobs([thresholds[0]], roi=ROI, x_stride=10, y_stride=5,pixels_threshold=10, area_threshold=10, merge=True): #模板匹配函数x=blob.area()for blob in img.find_blobs([thresholds[1]], roi=ROI, x_stride=10, y_stride=5,pixels_threshold=10, area_threshold=10, merge=True): #模板匹配函数y=blob.area()if x>y:x_num+=1else:y_num+=1if x_num>y_num:uart.write("1")
else:uart.write("2")
- 2. 机械臂
我这里为四自由度的舵机,抓取释放可分为如下四个步骤进行。
(1)初始化
rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL1, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_thread_mdelay(100);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL3, period, angle_135); rt_thread_mdelay(100);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(400);
(2)向下抓取
rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL1, period, angle_45); /* 爪子打开*/rt_thread_mdelay(100);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL2, period, angle_180); rt_thread_mdelay(100);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL4, period, angle_90); rt_thread_mdelay(400);
(3)抓到搬运
rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL1, period, angle_110); /* 爪子闭紧*/rt_thread_mdelay(300);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL2, period, angle_90); rt_thread_mdelay(100);
(4)放盒回正
rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL4, period, angle_165); rt_thread_mdelay(400);rt_pwm_set(pwm4_dev, PWM_DEV_CHANNEL1, period, angle_45); rt_thread_mdelay(400);
三、远程遥控
MCU之间采用蓝牙进行通信
- 遥控器
通过用ADC采集四个电位器信息和按键键值控制四足机器人或机械臂运动。
1. 数据采集
rt_uint8_t typeId=key_sw1_status;uploadpackT.linear = value[0]/22.75; // 4095/22.75=180°uploadpackT.angular = value[1]/22.75;uploadpackT.vra = value[2]/22.75;uploadpackT.vrb = value[3]/22.75;uploadpackT.switch_code = key_sw2_status;
2. 打包
int8_t pack(ProtocolBufferT *handler,uint8_t type, void* src, uint16_t size, uint8_t** dest,uint16_t* dest_size )
{assert(size+7 < handler->max_size);assert(type>0 && type < 128);handler->data[0] = PROTO_HEAD0;handler->data[1] = PROTO_HEAD1;handler->data[2] = size & 0xff;handler->data[3] = size >> 8;handler->data[4] = type;memcpy(handler->data+5, src, size );handler->pack_len = size;uint16_t sum = calc_sum(handler);handler->data[size+5] = sum & 0xff;handler->data[size+6] = sum >> 8;handler->data_ptr = size+7 ;if (dest) (*dest) = handler->data;if (dest_size) (*dest_size) = handler->data_ptr;return 0;
}
3. 验包
int8_t check_pack(ProtocolBufferT *handler)
{int8_t check_header = 1;do {check_header = 0;if (!(handler->data[0] == PROTO_HEAD0 && handler->data[1] == PROTO_HEAD1)){update_next_header(handler,1);check_header = 1;}if (handler->data_ptr < 5 ) {handler->status = 0;return 0;}handler->pack_len = *((uint16_t*) (&handler->data[2]));if (handler->pack_len + 7 >= handler->max_size){update_next_header(handler,1);check_header = 1;}} while(check_header);if (handler->data_ptr < handler->pack_len +7 ) {handler->status = 0;return 0;}uint16_t checksum = handler->data[handler->pack_len + 5] + (handler->data[handler->pack_len + 6]<<8);uint16_t sum = calc_sum(handler);if (sum == checksum){handler->status = 1;handler->type = handler->data[4];return handler->type;}// else checksum failedprintf("checksum failed\n");for(int i = 0 ; i < handler->pack_len; ++i) {printf("%02x ", handler->data[i]);}update_next_header(handler,1);handler->status = 0;return 0;
}
技术交流,联系下方wx即可
这篇关于基于四足机器人和机械臂的运动控制系统(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!