这是我的第一篇CSDN博客,写得很烂是肯定的,会有点伤眼睛,请事先做好准备。
本人是自动化类研一新生,即将在今年9月份入学,我也是接触Vrep不久,之前本科阶段都是在做嵌入式软硬件开发的工作,研究生阶段换了研究方向,要用到Vrep仿真,这篇文章就记录一下我的一个练手小项目,用Matlab+Vrep实现动态建图。
文章中有三个小工程:Vrep工程,Matlab工程与python工程,其中python工程就是写了一个小的遥控器来遥控小车动起来而已。
此外,这个工程是在windows下运行的。
视频链接:
(bilibili) Matlab+Vrep动态建图
Github链接:
点这里直接跳转
https://github.com/wangrui449966/Matlab_Vrep_2d_mapping
用法:
分别用Vrep、Matlab(我用的是R2019a 64-bit)、python(建议使用pyCharm)打开三个工程以后,
先运行Vrep仿真,然后运行Matlab和python工程,选中python工程的窗口,按键盘上的上下左右键来控制小车的运动,同时matlab会进行动态建图。
注:python需要安装pygame包(pip install pygame)
Vrep为了与其他语言联调,提供了很方便的remoteApi
在Vrep的安装目录中可以找到包含RemoteApi的.m文件的文件夹
[Vrep安装目录]\programming\remoteApiBindings\matlab\matlab
我们只要用到remApi.m与remoteApiProto.m即可
将这两个文件复制到自己的matlab工程的目录里,就可以调用Vrep的RemoteApi了。
由于RemoteApi的底层封装成了dll文件,需要将dll文件复制到matlab的相应文件夹下。
在 [vrep安装目录]\programming\remoteApiBindings\lib\lib\64Bit 中有 remoteApi.dll,将它复制到 [matlab安装目录]\bin\win64 中即可。
到此,带有RemoteApi的Matlab工程创建完毕。
在这个项目中,这不是重点,只是用python写了一个遥控器来控制小车的运动
在Vrep的安装目录中可以找到包含RemoteApi的.py文件的文件夹
[Vrep安装目录]\programming\remoteApiBindings\python\python
我们只要用到vrep.py与vrepConst.py即可
将这两个文件复制到自己的python工程目录里,就可以调用Vrep的RemoteApi了。
由于RemoteApi的底层封装成了dll文件,需要将dll文件复制到python工程目录下。
在**[vrep安装目录]\programming\remoteApiBindings\lib\lib\64Bit** 中有 remoteApi.dll,将它复制到python工程目录下即可。
这个项目中用到了两个终端(python端与matlab端)来与Vrep通信,所以需要为这两个终端各开一个端口
if (sim_call_type==sim_childscriptcall_initialization) then
simExtRemoteApiStart(66666)-- Socket Port=66666(for matlab)
在matlab中,添加如下代码即可连接到Vrep
vrep=remApi('remoteApi'); % vrep remoteApi remApi类实体
vrep.simxFinish(-1); % 关闭所有已经连接的remote,实测不会影响python终端,如果影响了,直接把这句删了完事
dr20ID=c_vrep.simxStart('127.0.0.1',66666,true,true,5000,5);%66666是小车的端口
if (sim_call_type==sim_childscriptcall_initialization) then
simExtRemoteApiStart(56666)-- Socket Port=56666(for python)
在python中,添加以下代码即可连接到Vrep
import vrep
# vrep.simxFinish(-1) # 断开所有已经连接的remote,这里不执行,避免把matlab中的连接断开
# 我直接把断开所有已经连接的remote给注释了,也没有测试不注释的情况下会不会影响matlab的连接
dr20ID = vrep.simxStart("127.0.0.1", 56666, True, True, 5000, 5)
Vrep工程脚本 本文主要就介绍打开Socket端口,至于激光雷达与小车在Vrep中的通信,本文不详细介绍,以后有时间专门另写一篇文章作详细介绍。
打开RemoteApi Socket端口:
在dr20的脚本文件中的初始化段添加如下代码,分别为matlab与python终端打开RemoteApi的Socket接口:
if (sim_call_type==sim_childscriptcall_initialization) then
simExtRemoteApiStart(66666)--WR:Socket Port=66666(for matlab)
simExtRemoteApiStart(56666)--WR:Socket Port=56666(for python)
在Github上传的工程中已经有比较详细的代码注释,本文将进一步讲解。
(太懒了,有空再写)
我之前是用C和C++比较多,学python还没有一个月,发现这个语言是真的很简单,包也很多很好用,而且作为脚本语言开发起来很方便,不用像CPP工程那样还需要繁琐的配置工程的一些步骤,但是总感觉少了灵魂。
import pygame as pg # pygame 包来读取键盘
import vrep
#参数,线速度参数和角速度参数
SET_LINE_SPEED = 3.0
SET_ROTATE_SPEED = 1.0
if True: # 初始化
# vrep初始化
# vrep.simxFinish(-1) # 断开所有已经连接的remote,这里不执行,避免把matlab中的连接断开
dr20ID = vrep.simxStart("127.0.0.1", 56666, True, True, 5000, 5)
if dr20ID < 0:
print("vrep_connection_failed")
exit()
else:
print("vrep_connection_success")
handle_left_wheel = vrep.simxGetObjectHandle(dr20ID, "dr20_leftWheelJoint_", vrep.simx_opmode_blocking)
handle_right_wheel = vrep.simxGetObjectHandle(dr20ID, "dr20_rightWheelJoint_", vrep.simx_opmode_blocking)
vrep.simxAddStatusbarMessage(dr20ID, "python_remote_connected\n", vrep.simx_opmode_oneshot)
# pygame初始化
pg.init()
window = pg.display.set_mode((320, 240))
pg.display.set_caption("vrep_car_control_window")
# 正常运行
end_flag = False
while not end_flag:
pg.time.delay(30)
# 显示,背景色
window.fill((100, 100, 100))
# pygame处理
for event in pg.event.get():
if event.type == pg.QUIT:
end_flag = True # 当窗口被关闭时,end_flag为真,退出循环
# 检测按键,并遥控小车,并更新显示
key_status = pg.key.get_pressed()
window_block_position = [160 - 25, 120 - 25]
v_line = 0.0
v_rotate = 0.0
if key_status[pg.K_UP] == 1:
window_block_position[1] -= 100
v_line += SET_LINE_SPEED
if key_status[pg.K_DOWN] == 1:
window_block_position[1] += 100
v_line -= SET_LINE_SPEED
if key_status[pg.K_LEFT] == 1:
window_block_position[0] -= 100
v_rotate -= SET_ROTATE_SPEED
if key_status[pg.K_RIGHT] == 1:
window_block_position[0] += 100
v_rotate += SET_ROTATE_SPEED
# 显示矩形
pg.draw.rect(window, (255, 0, 0), (window_block_position[0], window_block_position[1], 50, 50))
# 发送速度
vrep.simxSetJointTargetVelocity(dr20ID, handle_left_wheel[1], v_line + v_rotate, vrep.simx_opmode_streaming)
vrep.simxSetJointTargetVelocity(dr20ID, handle_right_wheel[1], v_line - v_rotate, vrep.simx_opmode_streaming)
pg.display.update()
pg.quit()
vrep.simxFinish(dr20ID)
print("python exit")