How to get the pose matrix of a bone?

I am trying to get the rotation of a bone in one keyframe and then subtract this rotation to another keyframe, but the problem I have is that the matrix is always the same.

This is my code. I commended the lines which does not work and added prints to present the problem.

import bpy
import math



ob = bpy.context.object
bpy.ops.object.mode_set(mode = 'POSE')
#ob.mode_set(mode = 'POSE')
print(ob)


action = ob.animation_data.action

#print(dir(bpy.ops.screen))

#Set the current frame to 0
frame = 0
bpy.context.scene.frame_set(frame)

print(dir(ob.pose.bones[0]))

#Store the matricies of the first pose
mats = []
for b in ob.pose.bones:
    mats.append(b.matrix.copy())
    
print(mats[14])
print(ob.pose.bones[14])
#Jump to the next pose an start looping all keys of the action



bpy.ops.screen.keyframe_jump()
while frame != bpy.context.scene.frame_current:
    bpy.context.scene.update()
    #print(mats[14])
    print(ob.pose.bones[14])
    print(ob.pose.bones[14].matrix)
    #for i in range(len(ob.pose.bones)):
    #    ob.pose.bones[i].matrix -= mat[i]
        
    
    
    #Set the frame to current and jump to the next key
    frame = bpy.context.scene.frame_current
    bpy.ops.screen.keyframe_jump()

I tried to use matrix but always returns the same.

Does anyone know how to get the actual rotations of a bone in a given frame and then subtract the rotation to another?

It’s stateful from when you last used the context of the object your looking at, trust me it’s necessary for a proper threading state . But you cannot use the addons started with blender for this through a bpy module loaded later or the text editor menu run script command without checking on the bpy.data.scenes[scene].frame_current
so check it and you will find the ops don’t modify them so you can run threads in the background seperate from the UI, basically if your gonna do it through the text editor use the bpy module you imported there for setting global’s you don’t want viewed in the UI. bpy.data.scenes[scene].frame_set before you do the looop cuz it could have been set long before to a different value!

You will have to save your changes with .keyframe_insert() like this:

ob.pose.bones[i].keyframe_insert(data_path=“location” ,frame=f)
ob.pose.bones[i].keyframe_insert(data_path=“rotation_quaternion” ,frame=f)

An additional problem is that you generally don’t substract matrices. If you want to get changes relative to the first pose, multiply your matrix by the inverse of the first matrix. For example, like this - note that the order is relevant, so try both.

ob.pose.bones[i].matrix = ob.pose.bones[i].matrix * mat[i].inverted()

ob.pose.bones[i].matrix = mat[i].inverted() * ob.pose.bones[i].matrix