【V-REP自学笔记(三)】用代码控制机器人

导语

在这一系列的V-REP自学笔记中,我们定了一个小目标,完成一个Demo。使用官方提供的KUKA公司的YouBot机器人模型来实验机器人的感知和控制过程,控制机器人从A点抓取物品,然后移动到B点将物品放置在B点的工作台上,这其中涉及到V-REP环境中的机器人感知和控制过程。没有看过前期学习笔记的读者,可以在文末找到往期文章地址。

在上一期的自学笔记中,我们讲述了V-REP软件的入门使用方法。在本期笔记中,我们将学习在V-REP中使用Lua脚本代码控制机器人的关节运动。话不多说,先放一个最终的效果视频:

1. YouBot机器人的关节

1.1 基础知识

KUKA公司的YouBot机器人由一个四轮的万向移动平台与一个带夹持器的5自由度机械手臂组成,能够实现复杂移动操控等功能,非常适合移动机器人的科研与教学应用。YouBot是一个由刚性结构构成的刚体(Rigid body)机器人。对于刚体机器人来说,其运动部分的基本组成结构是连杆和关节,为了能够在空间当中自由活动,机器人必须具有一定的自由度,而自由度是由关节确定的。本篇文章暂不讨论机器人连杆、关节和自由度的定义与计算方式,具体的过程将在后续的文章中逐一介绍,想要提前了解和学习有关知识的读者可以自行阅读机器人学的相关书籍,这里推荐2本个人觉得讲得比较透彻的机器人学书籍《Humanoid Robot》(中文译名:仿人机器人)和《Modern Robotics: Mechanics, Planning, and Control》(中文译名:现代机器人学)。第一本书是一位日本教授写的,适合学习仿人双足机器人相关的运动学和动力学建模知识,而第二本书更适合从事机械臂相关研究的读者。两本书的电子版下载方式见文末。

第二本书的纸质版比较贵,个人觉得没必要买纸质版,实在有需要纸质版书籍的,可点击下方购买地址:

1.2 YouBot机器人的整体视图

如图所示为YouBot机器人的整体视图,包括底盘、托盘和机械臂。底盘带有4个轮子,可以带动机器人在地面上移动,托盘用于放置物品,机械臂由5个旋转关节构成5自由度的机械臂。在机械臂的末端还安装有一个夹持机构,用于夹持物品。

1.3 YouBot的底盘关节

YouBot机器人的底盘关节由4个麦克纳姆轮(Mecanum wheel,简称麦轮)组成,与普通的固定轮只能前后方向的移动不同,麦轮还可以提供水平方向的移动。麦轮分为A轮和B轮,合理的麦轮搭配可以省略底盘的转向机构,甚至可以做到原地打转,因此这种带有4个麦克纳姆的底盘在移动式机器人中非常常见。这里不对麦克纳姆轮做详细介绍,有兴趣的读者可以观看下面这个视频,讲得非常清楚。

因此,我们可以通过对底盘的运动关节进行建模来构建小车底盘的运动学模型。本文暂不做介绍,欢迎关注后续文章。

1.4 YouBot的机械臂关节

YouBot机械臂一共有5个自由度,由5个旋转关节(A1-A5)和相应的连杆机构串联组成,是典型的串联型机械臂,每个关节的运动角度范围、关节运动方向和连杆长度由图中定义。在本文中,我们只针对每个关节进行单独的控制,暂不需要关注连杆长度,在后续的运动学建模过程中我们将会介绍如果通过关节和连杆的参数来构建机械臂的运动学模型。在本文中,我们只需要知道,V-REP已经给我们构建好了基本的关节模型与运动控制接口,我们调用相应的控制接口来控制各个关节就行了。首先展示一下V-REP官方提供给我们的YouBot机器人控制Demo,通过手动操作来展现控制效果。

接下来,我们将学习如何通过V-REP提供的代码控制接口来控制YouBot机器人的各个关节。

2. V-REP中基本的代码框架

V-REP中的编程与普通的编程思路有一点不一样(但与Gazebo类似),我们不需要从头开始编写整个控制框架,只需要在V-REP提供的框架中进行编码,构造自己的算法代码就行了。本文以Lua语言编写的脚本为例来介绍V-REP的代码控制接口,其他语言的接口和使用方式类似,这里暂不做介绍。Lua语言的使用方式与C/C++语言类似,有C/C++基础的读者很快可以上手,放一个Lua语言的教程:https://www.runoob.com/lua/lua-tutorial.html

如图所示,V-REP的控制脚本至少包含2部分:

  • 第1个是Main script,对应每一个Scene,一个Scene只有一个。这部分是V-REP软件运行时会自动加载的控制脚本,在实际使用时我们不用修改这里的内容,但是可以打开看看里面包含哪些部分。
  • 第2个是Child script,对应每一个模型以及模型当中的部分关节等,可以有多个。每一个模型都会包含一个跟自己绑定的Child script,如果涉及到更加底层的控制过程,我们可以给每一个关节、每一个传感器等都定义一个自己的Child script。本文中我们要做的就是修改YouBot机器人的Child script里面的代码来实现机器人的控制。

不管是Main script还是Child Script,都会包含一些基本函数(图中只是一部分,如果想要详细查询V-REP提供的API函数,可以在官网进行查询),不是每一个都一定要包含,可以根据实际需求选择。一般sysCall_init()、sysCall_cleanup()是默认包含的。V-REP在运行时后台自动调用这些函数。我们不能修改这4个函数的名字,否则V-REP在运行时无法找到对应的函数。

这些函数就是用来进行用户自定义功能的函数,编写好后,V-REP在运行时会自动的加载这几个函数的内容。这一点与Gazebo的思路一致,直观理解的话,就相当于用户自己写的是一个插件或者叫动态加载库,V-REP提供的这几个接口就是用来调用用户编写的动态加载库的,它的主体运行过程我们不用关心(例如如何去同步消息、如何更新可视化的过程等),只需要专注在自己要做的那部分就行了。

3. 使用Lua脚本代码控制YouBot

3.1 代码总览

首先,我们新建一个scene(File->New scene),保存这个scene到一个指定的路径下,并自定义一个名字,例如V-REP-YouBot-Demo-1。然后从左边的模型文件树中选择YouBot机器人,并鼠标拖动到右边的仿真环境中,此时我们可以看到,刚刚建立好的Scene中已经有了YouBot模型对应的相关Child script,当然,展开来看下面还有许多更底层的Child script,今天我们先不管其他的,只需要修改YouBot最顶层的Child script就行了。

双击YouBot的Child script,可以看到里面已经有写好的代码,这个是V-REP官方提供给我们的演示代码,前面的视频中已经演示了,不用管它,直接全选删除,然后加入自己写的代码,本文涉及的代码比较长,不方便在文中直接贴出来,见下图。完整的代码可以访问我的Github仓库下载:https://github.com/chauby/V-REP-YouBot-Demo.git

保存以后点击仿真运行的按钮,就可以看到实际控制的效果了。

3.2 核心代码详解

首先是从V-REP环境中加载各个关节的Handle。Handle是一种类似文件句柄的识别符,给它传递必要的参数来对它进行操作就可以控制对应的模型。因此,在sysCall_init()这个初始化的函数里面我们要获取YouBot机器人的各个关节的Handle,便于后面的控制代码利用。这里要说明的一点就是,与C/C++语言不同的是,Lua语言编写的代码中,所有定义的变量都默认为全局变量,在某个函数中定义的变量,其他函数可以直接使用,例如在sysCall_init()函数中定义的wheel_joints这个变量就可以被其他函数调用。而想要编写仅用于本函数的局部变量,需要使用local关键字,详见Lua语言教程:https://www.runoob.com/lua/lua-variables.html

-- Get YouBot Handle
    you_bot = sim.getObjectHandle('youBot')
    
    -- Prepare initial values for four wheels
    wheel_joints = {-1,-1,-1,-1} -- front left, rear left, rear right, front right
    wheel_joints[1] = sim.getObjectHandle('rollingJoint_fl')
    wheel_joints[2] = sim.getObjectHandle('rollingJoint_rl')
    wheel_joints[3] = sim.getObjectHandle('rollingJoint_rr')
    wheel_joints[4] = sim.getObjectHandle('rollingJoint_fr')
    
    -- Prepare initial values for five arm joints
    arm_joints = {-1,-1,-1,-1,-1} -- set default values
    for i=0,4,1 do
        arm_joints[i+1] = sim.getObjectHandle('youBotArmJoint'..i)
    end

然后是算法方面的代码。这部分代码定义了各个关节如何随时间运动,大致思路就是获取V-REP软件的仿真计时(非实际时间),并根据仿真的时间每隔10秒更新一次底盘轮子的运动方向,以及各个机械臂关节的目标运动角度。这里机械臂的目标角度是手动指定的一些值,读者可以自行修改来实现不同的控制效果。

simu_time = sim.getSimulationTime()

-- set the desired values for every 10 seconds simulation time, ps: not real time
if (simu_time % 10 == 0) then
    print('\nSimulation time = '..simu_time)
    
    -- Change the move direction for every 20 seonds simulation time
    if (simu_time % 20 == 0) then
        if go_forward_flag == 1 then
            go_forward_flag = -1 -- go backward
        else
            go_forward_flag = 1 -- go forward
        end
    end
    
    -- Set the desired joint angles of YouBot Arm
    if switch_pos_flag == 0 then
        print("Switch to position 1")
        desired_joint_angles = {180,0,0,0,0}
        switch_pos_flag = 1
    elseif switch_pos_flag == 1 then
        print("Switch to position 2")
        desired_joint_angles = {120*math.pi/180, 30.91*math.pi/180, 52.42*math.pi/180, 72.68*math.pi/180, 0}
        switch_pos_flag = 2
    else
        print("Switch to position 3")
        desired_joint_angles = {-120*math.pi/180, 30.91*math.pi/180, 52.42*math.pi/180, 72.68*math.pi/180, 0}
        switch_pos_flag = 0
    end   
end

第三部分就是控制关节进行运动了:

-- Apply the desired wheel velocities
    wheel_velocity = go_forward_flag*0.8;
    sim.setJointTargetVelocity(wheel_joints[1], wheel_velocity)
    sim.setJointTargetVelocity(wheel_joints[2], wheel_velocity)
    sim.setJointTargetVelocity(wheel_joints[3], wheel_velocity)
    sim.setJointTargetVelocity(wheel_joints[4], wheel_velocity)
      
    -- Apply the desired joint angles for each arm joint
    for i=1,5,1 do
        delta = desired_joint_angles[i] - current_joint_angles[i]
        if (math.abs(delta) > max_variation_allowed) then
            delta = max_variation_allowed*delta/math.abs(delta) -- limit the variation of each joint
        end
        
        sim.setJointPosition(arm_joints[i], current_joint_angles[i] + delta)
    end

轮子的控制过程是直接设定轮子的运动速度(包括运动方向),通过调用官方的速度耦控制API函数sim.setJointTargetVelocity()来实现对某个指定轮子的控制过程,我们根据时间改变了轮子的运动方向。

机械臂关节的控制过程是使用的位置控制API函数sim.setJointPosition()。由于该函数将会直接将指定关节设定为目标角度,而大家知道,在V-REP这类带有物理引擎的仿真软件中,带有质量的机械臂要遵循物理运动规律,具有一定的惯性,如果我们让关节直接从某一个位置“跳转”到目标位置,当目标位置与当前位置距离较远时,该关节会以最大加速度猛烈运动,会导致关节的运动发生冲击,引起机器震荡。在实际机器人上如果使用这样的控制方法将可能导致电机烧毁和机械臂损坏等问题,因此,这里有一个小技巧,在给定机械臂各个关节目标角度的时候,我们不能直接给一个最后的目标位置,需要设定关节最大的一个运动速度,并通过计算当前位置与目标位置的偏差,将其拆分为“多段”位置分时输入到机器人的关节当中,防止设定的目标位置不当时引发问题。

到此为止,在V-REP软件中,使用Lua脚本来控制YouBot的各个关节运动的基本过程已经介绍完了,但是大家可能发现了一个问题就是,如果只是对每一个关节单独设定角度,我们无法全局的去规划一个运动的动作,例如将机械臂的末端运动到一个指定的空间位置去。这部分的问题就是机器人运动学要解决的问题了,从下一篇笔记开始,我们将学习如何构建YouBot机器人的运动学模型,实现更加灵活的机器人动作规划过程。本项目涉及到的代码都将发布在Github上。

项目地址:https://github.com/chauby/V-REP-YouBot-Demo.git

参考教程

  1. V_REP:https://www.coppeliarobotics.com/helpFiles/index.html
  2. Lua语言:https://www.runoob.com/lua/lua-tutorial.html

书籍下载

谢谢支持,欢迎关注公众号:博士的沙漏。

  • 后台回复【HR】可获取《Humanoid robot》的电子版下载地址;
  • 后台回复【MR】可获取《Modern Robotics: Mechanics, Planning, and Control》的电子版下载地址。

往期回顾

  1. 【V-REP自学笔记(一)】平台介绍和软件安装
  2. 【V-REP自学笔记(二)】软件入门

作者知识有限,有不正确的地方还望读者能够指出来,大家共同学习和进步,不胜感激!

下一篇
举报

扫码关注腾讯云开发者

领取腾讯云代金券