机器人奇异点

来个简单的机器人来解释奇点(singularity)。
Scara机器人:
机器人奇异点【摘】

这个机器人实际上有4个自由度:3个平动(x,y,z)+1个转动(z)。
我们在此基础上再简化一下,留下2个平动(x,y),相当于我们只考虑在一个平面上的(x,y)坐标。简化模型为:
机器人奇异点【摘】

这个机器人很直观啦,你可以控制两个旋转关节来改变机器人的端点坐标。
这个机器人的奇异点是什么呢?
其实奇异点可以通过观察机器人端点的速度合成得到。
比如在当前的姿态下,机器人的端点可以产生的速度是由两个速度合成的:v1和v2.
v1是由于第一个旋转关节产生的;
v2是由于第二个旋转关节产生的;
机器人奇异点【摘】
可以看到两个速度矢量v1和v2在平面上没有共线,它们是独立的(记得线性代数里面的independent和dependent么)。
机器人的端点可以产生的速度就是这两个矢量的合矢量,这个合矢量可以是任意的吗?
来看两个分矢量:
这两个矢量的方向是定了的(在这一瞬间),但是大小呢?
大小是可变的,而且正比于相应的转动关节的角速度。(线速度=角速度*距离)
可以知道在v1和v2不共线的情况下,我们是可以通过调整v1和v2的大小来得到任意的合速度的(大小和方向)。

但是,当机器人处于这个姿态的时候:
机器人奇异点【摘】
可以看到两个速度矢量v1和v2在平面上共线了,它们是不独立的(independent)。
这个情况很直接,无论你怎样改变v1和v2的大小,你都只能合成出和v1(v2)方向相同的速度。
这就意味着你的机器人端点的速度不是任意的了,你只能产生某个方向上的速度。
这样机器人就奇异了。
在机器人控制上来说,就意味着,你一旦奇异了,你就不能随意控制你的机器人朝着你想要的方向前进了。
这也就是前面同学所谓的自由度退化、逆运动学无解。

转载于:https://www.cnblogs.com/kdp0213/p/9082416.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一种可能的Python程序实现,使用了逆运动学(inverse kinematics)算法和矩阵运算来计算机器人的关节角度,以避免奇异。 ```python import numpy as np # 机器人的链接长度 l1 = 1 l2 = 1 l3 = 1 # 定义机器人的初始关节角度 theta1 = 0 theta2 = 0 theta3 = 0 # 定义机器人当前位置和目标位置 current_pos = np.array([0, 0, 0]) target_pos = np.array([1, 1, 1]) # 定义机器人的运动学矩阵 def forward_kinematics(theta1, theta2, theta3): T01 = np.array([ [np.cos(theta1), -np.sin(theta1), 0, 0], [np.sin(theta1), np.cos(theta1), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) T12 = np.array([ [np.cos(theta2), -np.sin(theta2), 0, l1], [np.sin(theta2), np.cos(theta2), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) T23 = np.array([ [np.cos(theta3), -np.sin(theta3), 0, l2], [0, 0, -1, 0], [np.sin(theta3), np.cos(theta3), 0, 0], [0, 0, 0, 1] ]) T34 = np.array([ [1, 0, 0, l3], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]) T04 = T01.dot(T12).dot(T23).dot(T34) return T04[:3,3] # 避免奇异的逆运动学算法 def inverse_kinematics(current_pos, target_pos, theta1, theta2, theta3): # 计算机器人当前位置到目标位置的距离 delta_pos = target_pos - current_pos # 计算当前关节角度下机器人的末端位置 current_end_pos = forward_kinematics(theta1, theta2, theta3) # 计算当前末端位置到目标位置的距离 delta_end_pos = target_pos - current_end_pos # 计算雅克比矩阵 J = np.array([ [-l2 * np.sin(theta2) - l3 * np.sin(theta2 + theta3), -l3 * np.sin(theta2 + theta3), 0], [l2 * np.cos(theta2) + l3 * np.cos(theta2 + theta3), l3 * np.cos(theta2 + theta3), 0], [0, 0, l3] ]) # 如果雅克比矩阵的行列式为0,说明机器人处于奇异,无法进行运动 if np.linalg.det(J) == 0: return theta1, theta2, theta3 # 计算逆雅克比矩阵 J_inv = np.linalg.inv(J) # 计算关节角度的变化量 delta_theta = J_inv.dot(delta_end_pos) # 更新关节角度,并保证其合法性 theta1 += delta_theta[0] theta2 += delta_theta[1] theta3 += delta_theta[2] theta1 %= 2*np.pi theta2 %= 2*np.pi theta3 %= 2*np.pi return theta1, theta2, theta3 # 初始化机器人的位置 current_pos = forward_kinematics(theta1, theta2, theta3) # 不断移动机器人直到达到目标位置 while np.linalg.norm(target_pos - current_pos) > 0.01: # 调用逆运动学算法计算新的关节角度 theta1, theta2, theta3 = inverse_kinematics(current_pos, target_pos, theta1, theta2, theta3) # 计算末端位置并更新机器人位置 current_pos = forward_kinematics(theta1, theta2, theta3) # 输出目前的关节角度和末端位置 print(f"theta1: {theta1}, theta2: {theta2}, theta3: {theta3}, end_pos: {current_pos}") ``` 上述程序先定义了机器人的链接长度和初始关节角度,然后初始化当前位置和目标位置。通过 `forward_kinematics` 函数计算机器人的运动学矩阵以及末端位置,然后通过 `inverse_kinematics` 函数计算逆运动学的关节角度,同时避免机器人处于奇异。 程序的主要循环使用逆运动学移动机器人的位置,直到达到目标位置。在每次迭代时,计算当前的关节角度,更新机器人位置,并输出当前的角度和末端位置。 请注意,在实际机器人中,还需要考虑额外的因素,例如安全性、物理约束等,此处只给出了基本的示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值