机器人与机电一体化3D数字孪生机器-Day6

一、定位运动

1. 场景简介
  • 场景搭建:从简化场景开始,先创建一个立方体作为目标物体。
  • 模型创建:创建一个圆柱体作为机械轴(液压缸),放置在场景中。
  • 运动需求:机械轴需要向上移动到目标位置,然后收回。
  • 模型完善:添加另一个更大的圆柱体,模拟液压缸的外壳结构。
  • 尺寸调整:通过增加Y轴缩放值使液压缸更高,确保能完全伸展到目标位置。
  • 碰撞需求:液压缸需要与目标方块发生碰撞,因此需要启用碰撞检测。
  • 刚体设置:将液压缸转换为刚体,并设置为Is Kinematic(运动学模式),以便通过脚本控制其运动。
    • 开启Interpolate(插值)以平滑运动。
    • 开启Continuous(连续碰撞检测)以确保高速运动时碰撞检测的准确性。
2. 算法分析
  • 脚本创建:新建脚本命名为PistonPhysics,用于控制液压缸的伸缩运动。
  • 算法先行:在编写代码前,先理清实现往复运动的算法逻辑,涉及新的Unity函数。
1)保存液压缸的原始位置
  • 初始位置存储:在脚本中记录液压缸的起始位置(原点),因为液压缸需要从原点移动到目标点,再返回原点。
    • 液压缸当前位置记为位置二(Pos2)。
    • 目标方块位置记为位置一(Pos1)。
2)定义方向标志变量(布尔值)
  • 方向标志:使用布尔变量记录当前移动方向。
    • 值为true时:向目标位置移动。
    • 值为false时:向原点位置移动。
3)MoveTowards函数的使用
  • MoveTowards功能:将第一个参数物体以指定速度移向第二个参数物体。
    • 参数一:当前物体位置。
    • 参数二:目标位置。
    • 参数三:移动速度。
  • 函数效果:自动处理移动过程,将物体持续向目标位置推进。
4)使用Distance函数检测是否到达目标
  • Distance功能:计算两个物体之间的距离。
  • 到达判断:当距离为零(或接近零的极小值)时,判定物体已到达目标位置。
    • 若未到达:继续调用MoveTowards移动。
    • 若已到达:停止移动,执行后续逻辑。
5)到达目标后更改方向标志
  • 方向切换:当检测到已到达目标位置时,将方向标志取反。
    • 原本向目标移动(true)→ 改为向原点移动(false)。
    • 实现往复运动的转向逻辑。
6)MoveTowards参数顺序修正与反向移动
  • 参数顺序修正:MoveTowards中第一个参数应为移动的物体,第二个参数为移动目标。
    • 正确写法:MoveTowards(Pos2, Pos1, speed)------将液压缸移向目标方块。
    • 反向移动:MoveTowards(Pos2, originPos, speed)------将液压缸移回原点。
  • 易错点:参数顺序写反会导致物体向错误方向移动。
7)往复运动与伸展收缩控制
  • 往复运动:通过不断切换方向标志,实现液压缸在目标点和原点之间来回移动。
  • 伸缩控制:根据指令控制运动。
    • 按下"伸展":向目标位置移动。
    • 按下"收缩":返回原点位置。
8)定义刚体组件
  • 刚体引用:由于运动基于刚体,需要在脚本中定义私有刚体变量。
  • 变量声明:添加private Rigidbody变量,用于获取并控制液压缸的刚体组件。
3. 脚本编写
1)定义刚体
  • 刚体类型定义: 将活塞的刚体组件命名为 Piston,类型为 Rigidbody。
  • 获取刚体组件: 在 Start() 方法中,通过 GetComponent<Rigidbody>() 获取活塞上的刚体组件。
    • 该脚本将附加到活塞对象上,而活塞已具有刚体属性(在之前的课程中添加)。
    • 获取刚体后,才能访问其位置信息并进行物理移动。
2)存储原始位置
  • 原始位置变量: 声明 public Vector3 originalPos,用于保存活塞的初始位置。
  • 获取初始位置: 在 Start() 方法中,将 Piston.position 赋值给 originalPos。
    • 存储初始位置的目的:当活塞完成伸出动作后,能够返回原位。
    • 位置在3D环境中以 Vector3 类型存储。
3)定义目标位置
  • 目标位置变量: 声明 public Vector3 targetPos,用于存储活塞需要移动到的目标位置。
  • 目标位置获取: 在 Start() 方法中,通过 targetObject.position 获取目标位置。
    • 目标位置在初始化时计算一次,之后不会改变。
4)附加目标对象
  • 目标对象变量: 声明 public Transform targetObject,用于在Unity编辑器中拖拽指定目标物体。
    • 通过将目标立方体拖入脚本的目标对象字段,即可建立关联。
    • 使用 Transform 类型是因为需要访问物体的 position 属性。
5)计算位置并判断是否到达目标
  • 移动逻辑
    • 移动条件: 在 Update() 方法中,通过 if(start) 判断是否按下开始按钮。
    • 位置计算: 使用 Vector3.MoveTowards() 函数计算活塞的下一步位置。
      • 参数一:当前活塞位置 Piston.position
      • 参数二:目标位置 targetPos
      • 参数三:移动速度 speed * Time.deltaTime
    • 速度变量: 声明 public float speed = 8.0f,可在Unity编辑器中调整。
    • 刚体移动: 使用 Piston.MovePosition(pos) 移动刚体,而非直接修改 transform.position。
      • 这样活塞移动时能产生物理交互,可以推动其他物体。
  • 到达判断
    *
    • 距离计算: 使用 Vector3.Distance(Piston.position, targetPos) 计算活塞与目标位置的距离。
    • 到达条件: 当距离小于 0.01f 时,认为活塞已到达目标位置。
      • 使用 0.01f 而非 0,是因为浮点数精度问题,几乎接近零即可。
    • 状态切换: 到达目标后,将 MovingTwTarget 设为 false,表示不再向目标移动。
  • 返回逻辑
    *
    • 返回条件: 当 start == false 且 MovingTwTarget == false 时,活塞开始返回原始位置。
    • 返回移动: 使用 Vector3.MoveTowards(Piston.position, originalPos, speed * Time.deltaTime) 向原始位置移动。
    • 返回完成: 当活塞与原始位置距离小于 0.01f 时,将 MovingTwTarget 设为 true,准备下一次伸出。
    • 停止逻辑: 到达原始位置后,将 start 设为 false,停止整个运动循环。
  • 调试与修正
    *
    • 拼写错误: Trasform 应为 Transform,修正目标对象类型声明。
    • 括号问题: Vector3.Distance() 函数调用时括号不匹配,需要确保括号正确闭合。
    • 逻辑问题: 初始代码中 else if(start == false) 条件无法成立,因为外层 if(start) 已经要求 start 为 true。
      • 解决方案: 在到达目标位置时,先不重置 start,保持其为 true,让逻辑自然进入返回分支;当返回完成后,再将 start 设为 false。
  • 阈值调整
    *
    • 问题: 活塞停在气缸中间,未到达目标位置。
    • 原因: 到达判断的阈值 0.01f 过小,活塞在物理交互中未能精确到达。
    • 解决方案: 将阈值调整为 1.4f,允许活塞在更宽松的范围内判定为"已到达"。
      • 这样活塞能够更充分地伸出,完成推动动作。
6)附加脚本并测试
  • 附加脚本
    • 附加对象: 将 PistonPhysics 脚本附加到圆柱体(活塞)上。
    • 指定目标: 在Inspector面板中,将目标立方体拖入 targetObject 字段。
    • 运行测试: 点击开始按钮,观察活塞运动。
  • 物理交互测试
    • 添加交互物体: 创建一个新的立方体,放置在活塞运动路径上。
    • 添加刚体: 给立方体添加 Rigidbody 组件,使其可被物理交互。
    • 关闭重力: 取消勾选 Use Gravity,让立方体悬浮在指定位置。
    • 测试结果: 活塞伸出时能够推动立方体,实现物理交互效果。
      • 活塞运动具有真实的物理推动力,而非单纯的动画效果。
二、为传送带创建数字孪生
1. 数字孪生项目
1)设计介绍
  • 项目目标:对传送带进行数字孪生,包括动画处理和物理交互。
    • 对轴、滑轮和皮带进行动画处理。
    • 在传送带实际运行时,让产品与之进行物理交互。
  • 模型来源:提供预设的3D模型,无需自行设计。
    • 数字孪生通常基于已有的3D模型,可能来自自己或公司其他部门的设计。
    • 在开始数字孪生之前,需要先理解设计中的所有部件。
  • 本节任务:完成一个小型项目,将产品从一条传送带传递到另一条传送带。
    • 观察倾斜传送带的物理特性。
    • 建议先完成基础模块中的传送带章节和原型设计章节
  • 传送带组成部件:
    • 框架:传送带的基础支撑结构。
    • 皮带支架:位于传送带下方的一块金属板,帮助传送带保持稳定并始终拉紧,防止其下垂或产生弯曲。
    • 传送带本身:通过旋转将物体和产品从一个点移动到另一个点。
    • 驱动电机:传送带的动力来源。
      • 电机连接到一个轴,轴连接到滚筒,它们焊接或耦合在一起。
      • 电机旋转时,整个装置(滚筒和轴)都会旋转。
  • 轴承:使的运动更加顺畅。
  • 锁环:将轴固定到位,防止其向右移动。
  • 轴承座:固定轴承的金属或塑料零件,通过螺丝连接到框架上。
  • 驱动滚筒:由电机驱动,通过滚筒与传送带之间的摩擦带动传送带旋转。
  • 从动滚筒:位于传送带另一侧,没有电机驱动。
    • 滚筒两侧有轴承,用于平滑传送带的旋转。
    • 此处的滚筒旋转,但轴不旋转,与驱动侧不同。
  • 张紧器:用于调节传送带的松紧度。
    • 添加传送带后可能松动,需要将其调到最大张力。
    • 通过向前推动轴承座来实现张紧。
    • 最简单机制:放置一个金属块,上面有螺钉,旋转螺钉推动轴承座向前。
    • 两颗螺丝分别位于两侧,推动两个轴承座向前,使皮带拉紧并解决对齐问题。
2)修改模型
  • 导入模型:使用FBX文件格式,导入后可在Unity中调整大小和旋转。
    • 模型包含所有材质和内容。
    • 展开模型可查看所有部件,如轴承支架、螺丝等。
  • 解包预制件:修改模型前需要先解包预制件。
    • 预制件实例的子集无法被删除或移动,组件也无法重新排序。
    • 在预制件上选择"解包"后,即可自由修改模型。
    • 例如:在模型上添加一个方块,嵌入到身体附近。
  • 创建轴心点:解决旋转轴不正确的问题。
    • 直接旋转轴时,其旋转路径可能不符合预期。
    • 创建轴心点并隐藏它们,可以让轴围绕自身旋转。
    • 这对于后续动画制作非常重要。
三、知识小结

|------------|-------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|------|
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 液压缸运动逻辑 | 使用Vector3.MoveTowards实现活塞杆向目标位置移动,通过Vector3.Distance检测到达状态,布尔标志控制移动方向(目标/原点) | 移动方向切换条件:到达目标后需翻转movingToTarget标志;易混淆:MoveTowards第一个参数是移动物体,第二个是目标位置 | ⭐⭐⭐ |
| 刚体物理交互 | 活塞需添加Rigidbody组件,设置isKinematic(通过脚本控制),开启Interpolation和Collision Detection(连续检测)以实现碰撞推动效果 | 刚体移动使用rb.MovePosition()而非直接修改transform.position,否则物理交互失效;易混淆:isKinematic与isTrigger的区别 | ⭐⭐⭐⭐ |
| 到达判定阈值 | 距离判断使用< 0.01f作为近似零值,实际调试中需调整阈值(如1.4f)以解决因碰撞体尺寸导致的提前停止问题 | 阈值过小会导致活塞未完全伸展就停止;易混淆:Vector3.Distance与Vector3.Magnitude(差向量长度)的等价性 | ⭐⭐ |
| 传送带数字孪生结构 | 传送带由框架、皮带支架(稳定防下垂)、驱动滚筒(电机带动轴旋转)、从动滚筒(仅滚筒旋转,轴不转)、轴承座、张紧器(螺钉推动轴承座拉紧皮带)组成 | 驱动侧轴与滚筒焊接耦合,从动侧滚筒独立于轴旋转;易混淆:张紧器与轴承座的固定关系 | ⭐⭐⭐⭐ |
| 预制件解包与轴心调整 | 对导入的FBX模型,需通过Prefab > Unpack解除预制件约束才能修改子物体;旋转轴心需创建隐藏空物体作为父级,使轴绕自身Y轴旋转 | 不解包无法移动/删除子物体;易混淆:全局旋转与局部旋转(localRotation)的差异 | ⭐⭐⭐ |
| 物理交互实现 | 传送带上的产品需添加刚体(禁用重力或启用),通过活塞/传送带碰撞推动产品,实现真实物理反馈 | 产品需与传送带表面接触,且传送带运动需通过刚体移动而非动画;易混淆:碰撞检测模式(Continuous vs Discrete)的选择 | ⭐⭐⭐⭐ |

相关推荐
山顶夕景1 小时前
【VideoLLM】Agentic Video Understanding视频理解综述
agent·强化学习·1024程序员节·视频理解·agentic·多模态理解·grpo
可乐_不渴1 小时前
【Linux】 项目自动化构建工具makefile&& 版本管理Git&&第一个程序
linux·git·自动化·1024程序员节
爱喝雪碧的可乐1 小时前
OpenAI Codex完成率
大数据·人工智能·1024程序员节
要开心吖ZSH1 小时前
一次线上锁风暴复盘:号源表大范围 DELETE 的隐患与分批删除改造
数据库·mysql·行锁·1024程序员节·间隙锁·lockwaittimeout
Solange__1 小时前
文旅景区怎么用AI生成3D导览?从航拍采集、地标重建到网页漫游的完整方案
人工智能·3d·语言模型·自然语言处理·材质·贴图·1024程序员节
夏幻灵1 小时前
Web 渲染模式:SSR、CSR、SEO 与前后端分离
1024程序员节
m0_622023531 小时前
产业资本运作:新金融博弈下的产业链安全底盘搭建
大数据·深度学习·重构·1024程序员节
geats人山人海1 小时前
洛谷好题推荐 2026年10月24日
1024程序员节
扶尔魔ocy1 小时前
【C++开发】从裸指针到智能指针
c++·智能指针·1024程序员节