机器人坐标系详解

机器人坐标系详解

笔者虽然从事自动化工作十几年,但是对于机器人坐标系的理解始终是一知半解,最近认为吃透了坐标系的事,和广大同仁分享一下。

工业机器人的坐标系的五个坐标系:1、世界坐标系;2、机器人足部坐标系;3、基坐标系;4、法兰坐标系;5、工具坐标系

这五个坐标系是工业机器人空间位置和姿态的数学基础。可以把它们想象成一套从宏观到微观的定位系统。

为了让你更直观地理解,可以把整个机器人工作站想象成一个房间,把机器人想象成人的手臂。以下是详细的解释:

1. 世界坐标系 —— 房间的地标

  • 定义:这是一个固定不变的绝对坐标系,通常定义在整个工作站(房间)的某个角落。
  • 用途:用来描述房间里所有东西的绝对位置。比如:机器人站在哪里、传送带放在哪里、工件放在哪里,都是相对于世界坐标系的。
  • 理解:它相当于你房间里的经纬度或者墙角。无论你怎么移动,这个点的位置是固定不变的。

2. 机器人足部坐标系 —— 机器人脚下的地

  • 定义:这是一个位于机器人安装底座正下方的坐标系。通常Z轴垂直向上,指向机器人的身体。
  • 用途:在安装机器人时,我们需要把机器人足部坐标系校准到世界坐标系中去。如果机器人被移动了位置,它相对于世界坐标系的数值变了,但足部相对于机器人本身是固定的。
  • 理解:相当于你站立的那块地。无论你在房间的哪个位置站着,你的脚底相对于你的身体永远是固定的。

3. 基坐标系 —— 机器人的肩膀

  • 定义:位于机器人第一轴(腰部)的安装基座上。它是机器人内部的零点。
  • 用途:这是机器人自身的原点。当我们说机器人“回零”,指的就是机器人的各个轴回到一个机械确定的姿态,而这个零点就是基坐标系的原点。所有后续关节的运动计算(运动学解算)都是基于这个坐标系开始的。
  • 理解:相当于你的肩膀根部。它是你手臂所有运动的起点。

4. 法兰坐标系 —— 机器人的手腕

  • 定义:位于机器人第六轴(最后一个轴)末端的法兰盘中心。
  • 用途:这是机器人手臂的末端。当我们说机器人移动到了某个点,通常指的是这个法兰盘中心点移动到了某个位置。它也是安装工具(如焊枪、抓手)的地方。
  • 理解:相当于你的手腕关节

5. 工具坐标系 —— 手里拿着的笔尖

简单来说:
当你告诉机器人“去喝咖啡”时:

在编程中,我们通常操作的是工具坐标系(控制干活的位置)和世界/基坐标系(控制移动的方向)。

  • 定义:定义在工具(焊枪、吸盘、抓手)的有效工作点上。比如焊丝的端点、吸盘的中心点、夹爪的中心点。
  • 用途:这才是我们真正关心的操作点。我们编程时,其实是告诉机器人:“让工具坐标系的这个点,移动到工件的那个点去。”如果不设定工具坐标系,机器人只会把法兰盘移到那个点,而焊丝可能还离工件很远。
  • 理解:相当于你手里握着的一支笔的笔尖
  • 房间里有台机器人:世界坐标系
  • 机器人底座固定在房间某处:足部坐标系(将机器人放在房间里)
  • 机器人从底座开始运动:基坐标系(机器人自己的起点)
  • 机器人运动到手腕:法兰坐标系(连接工具的接口)
  • 世界坐标系告诉你咖啡杯在桌子上。
  • 基坐标系告诉你的手臂要从肩膀开始动。
  • 法兰坐标系是你的手腕要伸过去。
  • 工具坐标系确保是你的嘴唇(而不是额头)碰到了杯子。
    • 手腕上装了焊枪:工具坐标系(真正干活的点)
    • 以一台库卡KR22 R1610工业机器人为例,想象一个场景,在一个3m*3m的工作范围,机器人安装在中间(机器人安装在一个厚度为50mm的铁板底座上,铁板底座大小是一个1200mm*1200mm的正方形),然后在距离底座边缘有一个桌子,高度是1000mm,桌子上有十个杯子,然后机器人去抓取这个杯子,这个过程中应该如何设定坐标系,如何实现这个过程?
    • 建立“桌面”基坐标:为了编程方便,我们不会在世界坐标系里直接计算每个杯子的位置。更聪明的做法是,在桌子表面建立一个用户基坐标系。你可以用库卡提供的“三点法”来定义它[citation8]:
      • 在桌面上选一个点作为原点 (X0, Y0, Z0)
      • 沿桌面边缘选一个点确定X轴正方向。
      • 在桌面上选一个点确定XY平面。
        这个新坐标,比如命名为 BASE_DATA[10]。这样,桌面上任何点的坐标都变得非常简单直观-7
    • 测量“抓手”工具坐标:在示教器上,切换到工具坐标测量程序。手动移动机器人,让你的抓手中心从四个不同方向去触碰工作空间里的一个固定尖点。每碰一次,记录一个点。机器人软件会自动计算出抓手中心相对于法兰盘中心的精确位置-1。保存结果为 TOOL_DATA[1]
    • 手动示教第一个杯子
      • 在示教器上,将运行模式切换到 T1(手动慢速) 模式-6
      • 在程序里,先用指令指定本次运动使用的坐标系:
      • $BASE = BASE_DATA[10]  ; 告诉机器人,接下来的目标点坐标是基于“桌子”的
        $TOOL = TOOL_DATA[1]   ; 告诉机器人,我们要用“抓手中心”去到达目标点
        • 手动操作机器人,让抓手中心精确地对准第一个杯子的中心,然后记录下这个点 PICK1。这个点的坐标将会是相对于 BASE_DATA[10] 的一个简单数值,比如 (X100, Y200, Z80)
      • 编写程序,实现循环抓取:利用库卡的 LIN (线性运动) 指令和抓爪工艺指令,编写主程序-2-4
        • 移动到安全点:首先移动到杯子上方的一个安全高度。
        • 直线抓取:使用 LIN PICK1 指令,让TCP垂直下降到杯子位置。
        • 闭合抓爪:使用 SET Gripper[1]=TRUE 指令,控制抓手闭合,抓住杯子-2
        • 抬起并放置:再次提升到安全点,然后移动到放置区域。
        • 循环:利用数学运算或位置寄存器(PR),在 PICK1 的X或Y坐标上增加一个固定的偏移量(即杯子的间距),就可以生成抓取下一个杯子的新目标点,实现整个循环。
      • 通过这套“坐标系思维”,你的程序逻辑会变得异常清晰:它不再是一串晦涩的关节角度,而是在“桌面”这个平面上,用“抓手中心”去到达一个个“点”的直观过程
      • 世界坐标系大多数大多数情况下位于机器人足部,是不是说默认情况世界坐标系和基坐标系是重合的???在默认情况下,它们确实重合在同一点上。这个“重合”也恰恰是容易混淆的地方。为了帮你彻底理清,我们需要拆开来看“世界坐标系”和“基坐标系”这两个概念:
      • “世界坐标系默认位于机器人足部”的真正含义
        你提到的这个说法,其实是在描述一个事实:在库卡机器人的默认配置中,世界坐标系的原点被设置在了机器人的足部-1-2-3。这意味着,在没有做任何额外设定的情况下,机器人的“绝对零点”就在它自己脚下。
      • 基坐标系的“默认状态”
        同时,库卡机器人出厂时,基坐标系(Base)的默认配置也指向同一个点——世界坐标系的原点-2-3-5。这就像一个新买的手机,它的“响铃”模式默认就是“铃声+震动”。
      • 世界坐标系:是一个固定不变的“绝对地标”。它一旦被定义(比如就在足部),就雷打不动,是整个工作站所有空间位置的最终参考-6-8
      • 基坐标系:是一个可以移动的“工作台面”。它的存在就是为了让你根据工件的位置,在世界坐标系里定义一个新的、更方便编程的参考系-3-9
      • 世界坐标系:整个世界的绝对原点(默认在机器人足部)。
      • 机器人足部坐标系(RobRoot):位于机器人足部的固定点,它在默认配置下与世界坐标系完全一致-1-10
      • 基坐标系(Base):一个用户自定义的坐标系,默认与世界坐标系重合,但随后由用户移动并设定到具体的工件(如桌子、夹具)上
      • 现在再看之前设计的抓杯子程序就清晰了:
        定义 $BASE = BASE_DATA[10],这个动作就是把原本与世界坐标系重合的“基坐标”原点,搬到了桌面的一角。从此以后,程序里写的坐标 (X100, Y200, Z80),就变成了相对于桌面这个新原点的位置,而不是相对于机器人脚下那个绝对的“世界原点”。理解了这个“默认重合,但本质不同”的关系,就真正掌握了机器人空间定位的底层逻辑
      • 假设第一个杯子 (ROW=1, COL=1) 在桌面基坐标系下的位置为 {X 150, Y 100, Z 80},那是不是说A,B,C就是根据工具坐标系计算出来的呢?????
      • 不,这里的 A、B、C 并不是根据工具坐标系计算出来的,而是目标点相对于当前激活的基坐标系(这里是桌面基坐标系)的姿态角度,它描述了工具坐标系(TCP)在该点应该如何指向
      • 它告诉你抓手中心在法兰前方多远(X、Y、Z偏移)。
      • 它还告诉机器人,当抓手安装好后,工具本身的坐标轴方向是怎样的(例如,抓手的Z轴可能指向法兰的哪个方向)。
      • 这个数据是固定的,一旦标定好,在程序中通常不会改变。
      • X、Y、Z 是要求工具坐标系的原点(即TCP)必须到达的空间位置(在桌面基坐标系下)。
      • A、B、C 是要求工具坐标系的姿态——即它的三个坐标轴在空间中如何定向(同样相对于桌面基坐标系)。
      • 换句话说,A、B、C 告诉机器人:当你到达 (150,100,80) 这一点时,你手里抓着的那个工具(其坐标系已由 TOOL_DATA[1] 定义)必须旋转到 A=0°, B=0°, C=0° 这个姿态
      • 工具坐标系(TOOL_DATA):定义了工具自身的形状(相当于告诉你“笔有多长,笔尖在哪”)。
      • 目标点的 A、B、C:定义了工具应该以什么姿势去接触工件(相当于告诉你要“笔尖朝下写”还是“笔尖朝前画”)。
      • 在抓杯子的例子里,假设我们想让抓手垂直向下抓取杯子(TCP的Z轴垂直向下),并且抓手开口方向与杯子的把手对齐。那么:
      • 我们可能通过示教手动调整机器人,使抓手恰好以这个姿态对准杯子。
      • 记录下来的那个姿态值(A、B、C)就是任务要求的姿态,它依赖于 TCP 的定义(因为 TCP 的方向直接决定了抓手抓取时的方向),但并不是由 TCP “计算”出来的,而是由实际工艺决定的。
      • 你手里抓着的那个工具(其坐标系已由 TOOL_DATA[1] 定义)必须旋转到 A=0°, B=0°, C=0° 这个姿态,是指工具坐标系的原点必须在(150,100,80) 这一点旋转到A=0°, B=0°, C=0°这个方向吧?????
      • 你手里抓着的那个工具(其坐标系已由 TOOL_DATA[1] 定义)必须旋转到 A=0°, B=0°, C=0° 这个姿态,是指工具坐标系的原点必须在(150,100,80) 这一点旋转到A=0°, B=0°, C=0°这个方向吧

一句话总结

X、Y、Z 决定“手伸到哪里”,A、B、C 决定“手怎么伸出去”。 两者都是相对于基坐标系的目标位姿,而工具坐标系(TCP)则像一把尺子,告诉机器人“手”究竟在法兰的哪个位置、哪个朝向。

为什么容易混淆?

因为工具坐标系和目标点的姿态都涉及“角度”,但角色完全不同:

2. 目标点的 A、B、C 是什么?

当你写一个目标点 PICK_POS = {X 150, Y 100, Z 80, A 0, B 0, C 0} 时:

1. 工具坐标系(TCP)本身是什么?

工具坐标系(例如 TOOL_DATA[1])定义了工具中心点相对于机器人法兰盘的位置和姿态。它就像工具的“身份证”:

💡 一个清晰的层次关系

为了帮你更好地区分,可以这样理解它们的层次关系:

所以,在默认的初始状态下,你通过示教器看到的“世界”和“基坐标”是重合的,指向的都是机器人足部那个点。这看起来就像“一个东西两个名字”。

🎯 它们的本质区别:绝对与相对

虽然初始重合,但它们的“职责”完全不同,这正是它们最核心的区别:

第二步:实现抓取过程——从编程到动作

设定好坐标系后,我们就可以编写程序,指挥机器人去抓杯子了。整个过程的核心思想是:让机器人关心的“操作点”(TCP),移动到我们关心的“目标点”(杯子的位置)。

在开始抓取之前,我们需要先在机器人的“大脑”里定义好各个参考系的位置。根据你描述的场景,我们可以这样设定:

坐标系在本场景中的具体定义设置方法与目的
世界坐标系整个3m*3m工作空间的绝对零点,例如定在房间的某个角落。作为全局参考,它唯一且固定。所有其他元素(机器人、桌子)的位置最终都是基于它来确定的。
机器人足部坐标系位于1200mm*1200mm铁板底座的上表面中心。在安装机器人时,需要通过精确测量,将这个点校准到世界坐标系中。它连接了“全局世界”和“机器人自身”-3-8
基坐标系机器人第一轴(腰部) 的安装面中心,理论上与足部坐标系重合。这是机器人内部计算所有运动的起点-5。在库卡机器人控制柜里,它通常被预定义为$BASE = BASE_DATA[1](或0)。
法兰坐标系机器人第六轴末端的法兰盘中心。这是机器人的机械接口,是安装抓手的“手腕”,它的位置由机器人根据基坐标系和运动学模型自动计算得出。
工具坐标系(TCP)抓手中心点,即抓取杯子时,杯子中心应该到达的位置。这是最关键的一步-1。我们需要用“XYZ 4点法”或“6D法”在库卡示教器上精确测量出抓手中心相对于法兰盘中心的偏移量(X, Y, Z和角度A, B, C)-1-3。测量好的数据会保存为一个工具数据,例如 TOOL_DATA[1]

第一步:坐标系设定——为机器人的世界“画地图”

总结与关系

这五个坐标系构成了一个转换链条:

Read more

2025强网杯web wp

文章目录 * secret_value * 1️⃣ 读取代理传来的用户 ID * bbjv * 代码整体分析 * yamcs * ez_php * 日志系统 * CeleRace * PTer 一直想着复现一下把其他几道题看看,结果一拖就拖了这么多天 secret_value ai分析登进去就可以在dashboard处看到flag 但是在访问dashboard前还要经过装饰器函数login_required的检查 def login_required(view_func): @wraps(view_func) def wrapped(*args, **kwargs): uid = request.headers.get('X-User', '0') print(uid) if uid == 'anonymous'

搭建本地ASR系统全攻略:Fun-ASR WebUI + GPU算力部署指南

搭建本地ASR系统全攻略:Fun-ASR WebUI + GPU算力部署指南 在远程会议、智能客服和语音笔记日益普及的今天,语音转文字的需求正以前所未有的速度增长。然而,当我们把音频上传到云端识别时,是否曾想过这些声音里可能包含客户的敏感信息、内部讨论细节甚至个人隐私?更别提网络延迟带来的等待焦虑——说一句话,等三秒才出字幕,体验大打折扣。 这正是越来越多企业开始转向本地化ASR系统的原因。不依赖云服务、数据不出内网、响应更快、长期成本更低——听起来像理想方案,但实现起来真的那么难吗? 其实不然。随着 Fun-ASR 这类高性能开源语音模型的出现,加上 Fun-ASR WebUI 提供的图形化操作界面,现在只需一台配备GPU的普通服务器,就能搭建起一个接近实时、高精度的私有语音识别系统。本文将带你一步步落地这套方案,并深入解析其背后的关键技术如何协同工作,让本地语音识别不再是“实验室项目”,而是真正可用的生产力工具。 从一行命令说起:为什么这个启动脚本如此关键 我们先来看一段看似普通的启动命令: python app.py --host 0.0.0.0 --port

Django 学习笔记(第1篇)|请求篇:理解 request 对象,前端传参、后端接收

大家好,这是我 Django 学习日记的第一篇。作为正在学习前后端分离的开发者,我发现 ** 请求(request)** 是绕不开、也最容易混淆的知识点。 这篇我就把自己学到的、用到的 request 全部整理出来,讲清楚 request 到底是什么、有哪些参数、分别怎么用,适合和我一样正在入门的同学看。 一、request 到底是什么? 简单一句话:request 是前端传给后端的所有信息的集合。 可以把它理解成一个快递包裹: * 里面有前端发过来的数据 * 有请求方式(GET/POST/PUT/DELETE) * 有请求头(token、设备信息) * 有客户端 IP、请求路径等 只要前端发起请求,Django 就会把所有内容打包成一个 request 对象,自动传给视图。 不管是函数视图还是 DRF 的 APIView,第一个参数永远是