【仿真】ruckig在线轨迹生成器示例

该场景说明了使用 CoppeliaSim 中提供的 Ruckig 在线轨迹生成功能的各种方法:

1. 在线程脚本内使用单个阻塞函数(红色)

2. 在线程脚本中使用多个非阻塞函数(黄色)

3. 在非线程脚本中使用多个非阻塞函数(蓝色)

4.使用关节回调函数(绿色) 

-- 红色圆柱体  -- 线程化子脚本,使用sim.moveToPose:

-- 引入sim库
sim = require 'sim'-- Threaded child script, using sim.moveToPose:
-- 线程化子脚本,使用sim.moveToPose:function sysCall_init()-- 获取当前对象句柄h = sim.getObject('.')-- 获取速度图形对象句柄graph = sim.getObject('/Object_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Red cylinder', 'm/s', 0, {1, 0, 0})-- 设置图形流的变换   对图形流进行原始类型的变换,不进行缩放,但在垂直方向上偏移了0.0002个单位。-- graph: 图形对象的句柄,表示图形流所属的图形对象。-- stream: 图形流的句柄,表示要设置变换的图形流。-- sim.stream_transf_raw: 表示变换的类型,这里使用原始类型。-- 1: 表示缩放比例的因子,这里为1,表示不进行缩放。-- 0.0002: 表示平移的偏移量,这里设置为0.0002,表示在图形流上方偏移0.0002个单位。sim.setGraphStreamTransformation(graph, stream, sim.stream_transf_raw, 1, 0.0002)
endfunction sysCall_sensing()-- 获取对象速度的第三个分量(在z轴上的速度)sim.setGraphStreamValue(graph, stream, sim.getObjectVelocity(h)[3])--获取对象在Z方向速度
endfunction cb(tr, vel, accel, handle)-- 设置对象的姿态sim.setObjectPose(handle, tr)
endfunction sysCall_thread()-- 定义最大速度local maxVel = {0.02, 0.02, 0.02, 0.2}  -- vx, vy, vz in m/s, Vtheta is rad/s-- 定义最大加速度local maxAccel = {0.002, 0.002, 0.002, 0.02}  -- ax, ay, az in m/s^2, Atheta is rad/s^2-- 定义最大加加速度(在RML类型2下被忽略,即无穷大)local maxJerk = {0.001, 0.001, 0.001, 0.01}  -- is ignored (i.e. infinite) with RML type 2-- 获取起始姿态local startTr = sim.getObjectPose(h)-- 复制起始姿态作为目标姿态local goalTr = sim.copyTable(startTr)-- 将目标姿态的z分量增加0.5goalTr[3] = goalTr[3] + 0.5-- 使用sim.moveToPose移动到目标姿态   使机器人从当前姿态 (startTr) 移动到目标姿态 (goalTr),在移动过程中受到了速度、加速度和加加速度的限制,并在运动完成后调用回调函数 cb 来设置对象的姿态。-- -1: 表示移动的方式。在这里,-1 表示使用默认的移动方式,即线性插值。-- startTr: 表示起始姿态,即机器人当前的姿态。-- maxVel: 表示最大速度的限制,是一个包含四个元素的表,分别对应 x、y、z 方向的线速度和绕姿态的角速度。-- maxAccel: 表示最大加速度的限制,同样是一个包含四个元素的表,分别对应 x、y、z 方向的线加速度和绕姿态的角加速度。-- maxJerk: 表示最大加加速度的限制,同样是一个包含四个元素的表,但在这里被忽略,因为 RML (Robotics Motion Library) 类型 2 下其值被视为无穷大。-- goalTr: 表示目标姿态,即机器人要达到的目标位置和姿态。-- cb: 表示在运动完成后的回调函数,即运动结束后会调用此函数,这里是 cb(tr, vel, accel, handle)。-- h: 表示机器人对象的句柄,即要执行移动操作的对象。sim.moveToPose(-1, startTr, maxVel, maxAccel, maxJerk, goalTr, cb, h)
end

-- 红色关节  -- 线程化子脚本,使用sim.moveToConfig:

-- 引入sim库
sim = require 'sim'-- Threaded child script, using sim.moveToConfig:
-- 线程化子脚本,使用sim.moveToConfig:function sysCall_init()-- 获取当前对象句柄h = sim.getObject('.')-- 获取关节速度图形对象句柄graph = sim.getObject('/Joint_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Red joint', 'deg/s', 0, {1, 0, 0})-- 设置图形流的变换sim.setGraphStreamTransformation(graph, stream, sim.stream_transf_raw, 1, 0.02)
endfunction sysCall_sensing()-- 获取关节速度并将其转换为度/秒sim.setGraphStreamValue(graph, stream, sim.getJointVelocity(h) * 180 / math.pi)
endfunction cb(config, vel, accel, handle)-- 设置关节的位置sim.setJointPosition(handle, config[1])
endfunction sysCall_thread()-- 定义最大关节速度maxVel = 0.1 -- 弧度/秒-- 定义最大关节加速度maxAccel = 0.01 -- 弧度/秒^2-- 定义最大关节加加速度maxJerk = 0.001 -- 弧度/秒^3-- 移动到目标关节配置  使机器人的第一个关节从当前位置移动到目标位置0弧度,并受到了关节速度、关节加速度和关节加加速度的限制,在运动完成后调用回调函数 cb 来设置关节的位置。-- -1: 表示移动的方式。在这里,-1 表示使用默认的移动方式,即线性插值。-- {0}: 表示目标关节的配置,这里是一个包含一个元素的表,表示第一个关节的目标位置为0弧度。-- nil, nil: 表示不设置目标速度和目标加速度。-- {maxVel}: 表示最大关节速度的限制,是一个包含一个元素的表,表示第一个关节的最大速度。-- {maxAccel}: 表示最大关节加速度的限制,是一个包含一个元素的表,表示第一个关节的最大加速度。-- {maxJerk}: 表示最大关节加加速度的限制,是一个包含一个元素的表,表示第一个关节的最大加加速度。-- {179 * math.pi / 180}: 表示目标关节的位置范围,这里设置为179度转换为弧度。-- {0}: 表示不设置目标关节的速度。-- cb: 表示在运动完成后的回调函数,即运动结束后会调用此函数,这里是 cb(config, vel, accel, handle)。-- h: 表示机器人对象的句柄,即要执行移动操作的对象。sim.moveToConfig(-1, {0}, nil, nil, {maxVel}, {maxAccel}, {maxJerk}, {179 * math.pi / 180}, {0}, cb, h)
end

-- 黄色圆柱   -- 线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:

-- 引入sim库
sim = require 'sim'-- Threaded child script, using sim.ruckigPos and sim.ruckigStep:
-- 线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:function sysCall_init()-- 获取当前对象句柄h = sim.getObject('.')-- 获取速度图形对象句柄graph = sim.getObject('/Object_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Yellow cylinder', 'm/s', 0, {1, 1, 0})-- 设置图形流的变换sim.setGraphStreamTransformation(graph, stream, sim.stream_transf_raw, 1, 0.0001)
endfunction sysCall_sensing()-- 获取对象速度的第三个分量(在z轴上的速度)sim.setGraphStreamValue(graph, stream, sim.getObjectVelocity(h)[3])
endfunction sysCall_thread()-- 获取对象当前位置local p = sim.getObjectPosition(h)-- 构建当前位置、速度、加速度信息的表local currentPosVelAccel = {p[1], p[2], p[3], 0, 0, 0, 0, 0, 0}-- 定义最大速度、加速度、加加速度信息的表local maxVelAccelJerk = {0.02, 0.02, 0.02, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001} -- vx, vy, vz in m/s, ax, ay, az in m/s^2, jx, jy, jz is ignored (i.e. infinite) with RML type 2-- 定义目标位置和速度信息的表local targetPosVel = {p[1], p[2], p[3] + 0.5, 0, 0, 0} -- x, y, z in m, vx, vy, vz in m/s-- 创建Ruckig对象并初始化  创建一个用于进行三维运动规划的Ruckig对象,并初始化其参数。-- 3: 表示运动的维度,这里为3,表示是三维运动。-- 0.0001: 表示最小步长,即运动规划的最小时间间隔。-- -1: 表示运动类型。在这里,-1 表示使用默认的运动类型,即 RML (Robotics Motion Library) 类型 2。-- currentPosVelAccel: 表示当前位置、速度、加速度信息的表,包含9个元素,依次是x、y、z位置,线速度,角速度,线加速度,角加速度。-- maxVelAccelJerk: 表示最大速度、加速度、加加速度信息的表,包含9个元素,依次是x、y、z方向的最大速度、加速度和加加速度。-- {1, 1, 1}: 表示是否考虑每个维度的运动限制,这里都设置为1表示考虑所有维度的运动限制。-- targetPosVel: 表示目标位置和速度信息的表,包含6个元素,依次是x、y、z位置,线速度,角速度,线加速度。local rmlObject = sim.ruckigPos(3, 0.0001, -1, currentPosVelAccel, maxVelAccelJerk, {1, 1, 1}, targetPosVel)-- 启用步进模式local lb = sim.setStepping(true)result = 0while result == 0 do-- 在每个模拟步长内执行Ruckig运动规划的一步result, newPosVelAccel = sim.ruckigStep(rmlObject, sim.getSimulationTimeStep())if result ~= -1 then-- 更新对象的位置sim.setObjectPosition(h, newPosVelAccel)end-- 推进仿真sim.step()end-- 恢复仿真步进模式状态sim.setStepping(lb)-- 移除Ruckig对象sim.ruckigRemove(rmlObject)
end

--黄色关节   -- 线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:

-- 引入sim库
sim = require 'sim'-- Threaded child script, using sim.ruckigPos and sim.ruckigStep:
-- 线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:function sysCall_init()-- 获取当前对象句柄h = sim.getObject('.')-- 获取关节速度图形对象句柄graph = sim.getObject('/Joint_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Yellow joint', 'deg/s', 0, {1, 1, 0})-- 设置图形流的变换sim.setGraphStreamTransformation(graph, stream, sim.stream_transf_raw, 1, 0.01)
endfunction sysCall_sensing()-- 获取关节速度并将其转换为度/秒sim.setGraphStreamValue(graph, stream, sim.getJointVelocity(h) * 180 / math.pi)
endfunction sysCall_thread()-- 定义最大关节速度maxVel = 0.1 -- 弧度/秒-- 定义最大关节加速度maxAccel = 0.01 -- 弧度/秒^2-- 定义最大关节加加速度maxJerk = 0.001 -- 弧度/秒^3-- 创建Ruckig对象并初始化  创建一个用于进行单轴关节运动规划的Ruckig对象,并初始化其参数。-- 1: 表示运动的维度,这里为1,表示是单轴运动(关节运动)。-- 0.0001: 表示最小步长,即运动规划的最小时间间隔。-- -1: 表示运动类型。在这里,-1 表示使用默认的运动类型,即 RML (Robotics Motion Library) 类型 2。-- {0, 0, 0}: 表示当前位置、速度、加速度信息的表,包含3个元素,依次是关节的当前位置、速度和加速度。-- {maxVel, maxAccel, maxJerk}: 表示最大速度、加速度、加加速度信息的表,包含3个元素,依次是关节的最大速度、加速度和加加速度。-- {1}: 表示是否考虑每个维度的运动限制,这里设置为1表示考虑所有维度的运动限制。-- {179 * math.pi / 180, 0, 0}: 表示目标位置、速度、加速度信息的表,包含3个元素,依次是关节的目标位置、速度和加速度。这里将179度转换为弧度。rmlObject = sim.ruckigPos(1, 0.0001, -1, {0, 0, 0}, {maxVel, maxAccel, maxJerk}, {1}, {179 * math.pi / 180, 0, 0})-- 启用步进模式local lb = sim.setStepping(true)result = 0while result == 0 do-- 在每个模拟步长内执行Ruckig运动规划的一步result, newPosVelAccel = sim.ruckigStep(rmlObject, sim.getSimulationTimeStep())if result ~= -1 then-- 更新关节的位置sim.setJointPosition(h, newPosVelAccel[1]) -- 或者根据关节模式使用 sim.setJointTargetPositionend-- 推进仿真sim.step()end-- 恢复仿真步进模式状态sim.setStepping(lb)-- 移除Ruckig对象sim.ruckigRemove(rmlObject)
end

--蓝色圆柱体    -- 非线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:

function sysCall_init()-- 获取当前对象句柄h = sim.getObject('.')-- 获取速度图形对象句柄graph = sim.getObject('/Object_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Blue cylinder', 'm/s', 0, {0, 0.5, 1})-- 获取对象当前位置local p = sim.getObjectPosition(h)-- 构建当前位置、速度、加速度信息的表local currentPosVelAccel = {p[1], p[2], p[3], 0, 0, 0, 0, 0, 0}-- 定义最大速度、加速度、加加速度信息的表local maxVelAccelJerk = {0.02, 0.02, 0.02, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001} -- vx, vy, vz in m/s, ax, ay, az in m/s^2, jx, jy, jz is ignored (i.e. infinite) with RML type 2-- 定义目标位置和速度信息的表local targetPosVel = {p[1], p[2], p[3] + 0.5, 0, 0, 0} -- x, y, z in m, vx, vy, vz in m/s-- 创建Ruckig对象并初始化rmlObject = sim.ruckigPos(3, 0.0001, -1, currentPosVelAccel, maxVelAccelJerk, {1, 1, 1}, targetPosVel)
endfunction sysCall_sensing()-- 获取对象速度的第三个分量(在z轴上的速度)sim.setGraphStreamValue(graph, stream, sim.getObjectVelocity(h)[3])
endfunction sysCall_actuation()-- 如果Ruckig对象存在,则执行一步运动规划if rmlObject thenlocal result, newPosVelAccel = sim.ruckigStep(rmlObject, sim.getSimulationTimeStep())-- 如果运动规划成功,则更新对象的位置if result ~= -1 thensim.setObjectPosition(h, newPosVelAccel)end-- 如果运动规划完成或出错,则移除Ruckig对象if result == 1 or result == -1 thensim.ruckigRemove(rmlObject)rmlObject = nilendend
endfunction sysCall_cleanup()-- 在清理阶段,确保移除Ruckig对象if rmlObject thensim.ruckigRemove(rmlObject)end
end

--蓝色关节   -- 非线程化子脚本,使用sim.ruckigPos和sim.ruckigStep:

function sysCall_init()-- 获取当前关节对象句柄h = sim.getObject('.')-- 获取关节速度图形对象句柄graph = sim.getObject('/Joint_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Blue joint', 'deg/s', 0, {0, 0.5, 1})-- 定义最大关节速度maxVel = 0.1 -- 弧度/秒-- 定义最大关节加速度maxAccel = 0.01 -- 弧度/秒^2-- 定义最大关节加加速度maxJerk = 0.001 -- 弧度/秒^3-- 创建Ruckig对象并初始化rmlObject = sim.ruckigPos(1, 0.0001, -1, {0, 0, 0}, {maxVel, maxAccel, maxJerk}, {1}, {179 * math.pi / 180, 0, 0})
endfunction sysCall_sensing()-- 获取关节速度并将其转换为度/秒sim.setGraphStreamValue(graph, stream, sim.getJointVelocity(h) * 180 / math.pi)
endfunction sysCall_actuation()-- 如果Ruckig对象存在,则执行一步运动规划if rmlObject thenlocal result, newPosVelAccel = sim.ruckigStep(rmlObject, sim.getSimulationTimeStep())-- 如果运动规划成功,则更新关节的位置if result ~= -1 thensim.setJointPosition(h, newPosVelAccel[1]) -- 或者根据关节模式使用 sim.setJointTargetPositionend-- 如果运动规划完成或出错,则移除Ruckig对象if result == 1 or result == -1 thensim.ruckigRemove(rmlObject)rmlObject = nilendend
endfunction sysCall_cleanup()-- 在清理阶段,确保移除Ruckig对象if rmlObject thensim.ruckigRemove(rmlObject)end
end

--绿色关节 -- 线程化子脚本,使用sim.moveToConfig:

function sysCall_init()-- 获取当前关节对象句柄h = sim.getObject('.')-- 获取关节速度图形对象句柄graph = sim.getObject('/Joint_Velocity_Graph')-- 创建图形流stream = sim.addGraphStream(graph, 'Green joint', 'deg/s', 0, {0, 1, 0})-- 设置图形流的变换sim.setGraphStreamTransformation(graph, stream, sim.stream_transf_raw, 1, -0.01)
endfunction sysCall_sensing()-- 获取关节速度并将其转换为度/秒sim.setGraphStreamValue(graph, stream, sim.getJointVelocity(h) * 180 / math.pi)
endfunction sysCall_thread()-- 定义最大关节速度maxVel = 0.1 -- 弧度/秒-- 定义最大关节加速度maxAccel = 0.01 -- 弧度/秒^2-- 定义最大关节加加速度maxJerk = 0.001 -- 弧度/秒^3-- 通过设置关节的目标位置,触发关节的回调函数sim.setJointTargetPosition(h, 179 * math.pi / 180, {maxVel, maxAccel, maxJerk})
endfunction sysCall_joint(inData)-- 用户可以在这里自由实现回调函数-- 由于该函数没有返回任何值,调用将被重定向到场景层次结构的上层-- 并最终由主脚本中的默认关节回调函数处理
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/177606.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于闪电搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神…

PyG(torch_geometric)的MessagePassing详解

1. 提出MessagePassing的目的 MessagePassing是图神经网络(Graph Neural Networks,GNNs)的一个基础组件,它被设计用来处理图形数据的问题。在图形数据中,数据点(节点)之间的关系(边…

【工具流】WSL2安装

一些废话 最近看到了PKU出品的cs自学指南,想要跟着里面的自学路径学国外的优质课程,无奈大多数pre教程里面都是直接Linux环境下的操作,并且我在CSwiki看到了那个熟悉的上学期学了一点的missing-semester课。 上学期自学missing-semester的时候…

Windows系统Mysql数据库、文件夹自动备份

一、批处理bat文件编写 批处理命令如下,使用时需要将相关参数修改为实际参数 echo off color 0a chcp 65001::数据库备份文件及模型文件备份的根路径 SET BACKUP_DIRZ:\backup ::**************************************配置MySQL数据库备份相关参数*************…

谷歌提出AGI的6大原则,和5大能力等级

随着ChatGPT等大模型的出现,AGI概念正在从哲学层面快速转向实际应用落地,并且ChatGPT已经展示出了初级AGI的功能(如AutoGPT),有不少专家认为,AGI时代可能在10年内到来。 因此,需要一个明确的技术框架来讨论和衡量不同…

深度学习+opencv+python实现车道线检测 - 自动驾驶 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &am…

学好Python-新手小白如何做?

新手小白如何学好Python?有哪些参考方法吗?这是一个老生常谈的话题了。今天为大家带来两位前辈的分享,他们给出了非常实用的方法和思路,希望对你有所帮助。 1、多练,两个字:多练 如果真的要说方法可以参考如下: ①…

Acrobat Pro DC 2023 中文版

Acrobat Pro DC 2023是PDF编辑和管理软件,具有以下优点: 更好的安全性:Acrobat Pro DC 2023采用了新的安全功能,包括加密、数字签名等,可以更好地保护PDF文件的安全性。 更高的速度和性能:Acrobat Pro DC …

19C进入数据库出现问号

问题情况如图所示: 解决方法: su - oracle echo "NLS_LANGAMERICAN_AMERICA.ZHS16GBK;export NLS_LANG" >> ~/.bash_profilesource ~/.bash_profileofile

重生奇迹mu圣导师加点

重生奇迹mu圣导师加点:要攻击高可以加力量,平衡系建议加点力量600~800,智力200~400,敏够装备要求,统帅1000,其余加体力。 圣导师靠加力量培养高攻圣导师不现实,建议玩家练魔,低级圣…

【Linux】非堵塞轮询

堵塞轮询: 堵塞轮询是我们最简单的一种等待方式也是最常应用的等待方式。 但是,一旦阻塞等待也就意味着我们当前在进行等待的时候,父进程什么都干不了。 非堵塞轮询: 其中非阻塞等待,是等待的一种模式, 在…

图论14-最短路径-Dijkstra算法+Bellman-Ford算法+Floyed算法

文章目录 0 代码仓库1 Dijkstra算法2 Dijkstra算法的实现2.1 设置距离数组2.2 找到当前路径的最小值 curdis,及对应的该顶点cur2.3 更新权重2.4 其他接口2.4.1 判断某个顶点的连通性2.4.2 求源点s到某个顶点的最短路径 3使用优先队列优化-Dijkstra算法3.1 设计内部类…