Blender使用脚本控制骨骼旋转2.0

下位机读取传感器四元数(四元数是一种用于表示三维空间中旋转的方法,它由一个实部和三个虚部组成),通过串口读取数据并更新 Blender 中的骨骼(Armature)的旋转。代码结合了 Blender 的 Python API 和串口通信,主要用于将外部设备(如传感器或运动捕捉系统)的数据映射到 Blender 中的骨骼上。

一.功能概述


下位机读取传感器四元数(四元数是一种用于表示三维空间中旋转的方法,它由一个实部和三个虚部组成),通过串口读取数据并更新 Blender 中的骨骼(Armature)的旋转。这段代码结合了 Blender 的 Python API 和串口通信,主要用于将外部设备(如传感器或运动捕捉系统)的数据映射到 Blender 中的骨骼上。跟上一篇帖子不一样的是这一篇处理了10个关节的数据,上一篇只处理了2个。本篇将代码集成在一个python file中,代码解释会比上一篇更加详细。下位机代码在上上篇帖子。

上一篇帖子里面有关于使用四元数控制骨骼旋转的详细解释,在这里就不赘述了,导航:Blender使用脚本控制骨骼旋转1.0

二.代码解析部分

1.导入必要的库

这些库包括Blender的API、时间处理、系统操作、串口通信和科学计算等。

import bpy
import time
import sys
import serial
import glob
import numpy as np
  • bpy: Blender的Python API,用于操控Blender环境。
  • time: 时间相关的操作。
  • sys: 系统级操作,如修改路径。
  • serial: 用于串口通信。
  • glob: 文件路径操作,但在本代码中未实际使用。
  • numpy: 科学计算库,主要用于四元数运算。

2.串口配置

设置串口端口和波特率,并尝试打开串口。

FPS = 60
# 串口配置
port = 'COM10'  # 指定串口号,根据实际情况修改
baudrate = 57600  # 波特率,根据实际情况修改

# 创建串口对象
ser = serial.Serial(port, baudrate, timeout=1)
if ser.isOpen():
    print(f"串口 {
     port} 已打开,波特率 {
     baudrate}")
else:
    print(f"无法打开串口 {
     port}")
  • 设置帧率FPS为60。
  • 配置串口端口port和波特率baudrate,并尝试打开串口。如果成功打开,打印成功信息,否则打印失败信息。

3.获取Blender场景和骨骼对象与骨骼的具体部分

获取当前Blender场景和名为“骨架”的骨骼对象。

# # Get the whole bge scene
# scene = bge.logic.getCurrentScene()
# # Helper vars for convenience
# source = scene.objects
# # Get the whole Armature
# main_arm = source.get('Armature')
# ob = bge.logic.getCurrentController().owner
# 获取当前场景
scene = bpy.context.scene
# 获取 'Armature' 骨骼对象
armature = bpy.data.objects["骨架"]
# 获取当前对象(这里假设是骨骼对象的所有者,可以根据实际情况修改)
ob = bpy.context.active_object

# get the bones we need
bone_upper_arm_R = armature.pose.bones.get("armUp.R")
bone_lower_arm_R = armature.pose.bones.get("armDown.R")
bone_upper_arm_L = armature.pose.bones.get("armUp.L")
bone_lower_arm_L = armature.pose.bones.get("armDown.L")
bone_trunk = armature.pose.bones.get("trunk.001")
bone_head = armature.pose.bones.get("head.001")
bone_upper_leg_R = armature.pose.bones.get("legUp.R.001")
bone_lower_leg_R = armature.pose.bones.get("legDown.R.001")
bone_upper_leg_L = armature.pose.bones.get("legUp.L.001")
bone_lower_leg_L = armature.pose.bones.get("legDown.L.001")
  • 获取当前Blender场景。
  • 获取名为骨架的骨骼对象。
  • 获取当前活动对象。

4.定义四元数运算函数

四元数乘法函数,用于旋转计算。

def multiplyQuaternion(q1, q0):
    w0, x0, y0, z0 = q0
    w1, x1, y1, z1 = q1
    return np.array([-x1 * x0 - y1 * y0 - z1 * z0 + w1 * w0,
                     x1 * w0 + y1 * z0 - z1 * y0 + w1 * x0,
                     -x1 * z0 + y1 * w0 + z1 * x0 + w1 * y0,
                     x1 * y0 - y1 * x0 + z1 * w0 + w1 * z0], dtype=np.float64)

5.设置骨骼旋转的函数

根据四元数设置骨骼的旋转。

def setBoneRotation(bone, rotation):
    w, x, y, z = rotation
    bone.rotation_quaternion[0] = w
    bone.rotation_quaternion[1] = x
    bone.rotation_quaternion[2] = y
    bone.rotation_quaternion[3] = z

关于四元数控制骨骼旋转看上一篇就行,这里不再赘述。导航一下:Blender使用脚本控制骨骼旋转1.0

6.更新角度的函数(!!重点!!)

根据从串口接收到的数据更新骨骼的旋转。该函数 updateAngles 是整个代码的核心之一。它的作用是将从串口接收到的角度数据应用到Blender中的骨骼Armature上。具体来说,它首先将输入的角度数据转换为适当的格式,然后计算各个骨骼部分的相对旋转,并最终将这些旋转应用到相应的骨骼上。

①将角度数据转换位NumPy数组:
  • 以便进行后续的四元数运算。
lowerarmR_out = np.array([angles[0][0], angles[0][1], angles[0][2], angles[0][3]])
... ...
②计算各个骨骼部分的相对旋转:
  • trunk_invtrunk_out 的共轭四元数,用于计算 head_rel
  • head_rel 是头部相对于躯干的旋转。
  • upperarmR_inv 是右上臂的共轭四元数,用于计算 lowerarmR_rel
  • 依此类推,计算其他骨骼部分的相对旋转。
trunk_inv = trunk_out * np.array([1, -1, -1, -1])
head_rel = multiplyQuaternion(trunk_inv, head_out)
upperarmR_inv = upperarmR_out * np.array([1, -1, -1, -1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值