How to solve these warnings

I made an extension witch could apply force in an rigid body and the direction and applying position can change along with the rigid body.
I apply force by this

def force_apply(self):
self.update()
trans_conv = array_sub(self.ori_trans, self.apply_pos)
angle_conv = array_sub(self.curr_rot, self.ori_rot)
new_dir = trans_coordinate(self.dir, angle_conv)
new_pos = trans_position(trans_conv, angle_conv, self.curr_trans)
force = carb.Float3(self.forcesize*new_dir[0]1000, self.forcesizenew_dir[1]1000, self.forcesizenew_dir[2]*1000)
new_pos_gf = Gf.Vec3f(new_pos[0], new_pos[1], new_pos[2] )
get_physx_interface().apply_force_at_pos(self.path, force, new_pos_gf)
self.timer = threading.Timer(1/24,self.force_apply)
if self.apply == 1:
self.timer.start()
else:
return 0
While running , these warnings were reported

Hi,
do you run the simulation in async mode? Check on a PhysicsScene in advanced settings if async simulation is enabled. If so, then you need to apply the forces once simulation is complete.

I have turned Asynchronous Simulation on in advanced settings , however , those errors are still reported. But forces are applied correctly

Ah I did probably not said it right, you should not have async enabled.

But looks like you are getting the errors anyway, can you please share with me more of the python code. Especially the part when your update is called?

I will try to reproduce on my side to see what the problem might be.

Thanks!
Ales

The function that apply the force is what I showed before
These are the rest of the functions:

def trans_coordinate(x=[0, 0, 0], angle=[0, 0, 0]):
x = np.mat([[x[0]], [x[1]], [x[2]]])

RX = np.mat([[1, 0, 0], [0, math.cos(angle[0]), -math.sin(angle[0])], [0, math.sin(angle[0]), math.cos(angle[0])]])
RY = np.mat([[math.cos(angle[1]), 0, math.sin(angle[1])], [0, 1, 0], [-math.sin(angle[1]), 0, math.cos(angle[1])]])
RZ = np.mat([[math.cos(angle[2]), -math.sin(angle[2]), 0], [math.sin(angle[2]), math.cos(angle[2]), 0], [0, 0, 1]])
R = (np.mat(RX))*(np.mat(RY))*(np.mat(RZ))  #旋转矩阵
x = (np.mat(R))*(np.mat(x))
x = np.transpose(x)
x = [x[0, 0], x[0, 1], x[0, 2]]  #转换后x'
return x

def array_sub(a1=[0, 0, 0], a2=[0, 0, 0]):
con = [0, 0, 0]
for i in range(len(a1)):
con[i] = a1[i] - a2[i]
return con

def trans_position(tc, ac, trans):
tc = trans_coordinate(tc, ac)
po = array_sub(trans, tc)
return po

def quat_to_eular(quat = [0.0, 0.0, 0.0, 0.0]):
angle = [math.atan2(2*(quat[0]*quat[1]+quat[2]quat[3]), (1-2(quat[1]*quat[1]+quat[2]quat[2]))),
math.asin(2
(quat[0]*quat[2]-quat[3]quat[1])),
math.atan2(2
(quat[0]*quat[3]+quat[1]quat[2]), (1-2(quat[2]*quat[2]+quat[3]*quat[3])))]
return angle
These functions will enable the direction and applying position of the force change along with the rigid body

def update(self):
self.curr_trans, self.curr_rot_quat = self.get_rigid_body_pos_rot(self.path)
self.curr_rot = quat_to_eular(self.curr_rot_quat)

This function reads current position and rotation of the rigid body.
self.apply in former function is a mark witch represents whether the force should be applied.

Right, but something needs to call you the update, how do you register to the update calls? I am interested in what is calling your update function. This is the missing piece, so that I know when/who calls the update.

In force_apply function,

self.timer = threading.Timer(1/24,self.force_apply)
if self.apply == 1:
self.timer.start()
else:
return 0
This part will call update and apply the force 24 times per second

Ok I see now, thanks I missed that.

So then you are writing indeed when simulation is running. We dont have double buffering for this use case.
I would recommend to use Kit update loop to get an update that is not called in the middle of a simulation run:

        def on_update(e):
            dt = e.payload["dt"]

        state.update_sub = omni.kit.app.get_app().get_update_event_stream().create_subscription_to_pop(on_update)

How does this function work.
And the reason why I use that loop is I noticed that if the function get_physx_interface().apply_force_at_pos() is use for one time , the force will only be applied for a short time. Is there any way to apply the force continuously while the position and direction change along with the rigid body?

Yes, its applied for one frame, if you want to apply it for every single physics step, you should use this function:

            def on_update(dt):
                    apply force

            sub = omni.physx.get_physx_interface().subscribe_physics_step_events(on_update)

So you subscribe to physics stepping, after each individual physics step you get a callback where you can apply new forces.

In next release we also add PhysxForceAPI that would allow you to position an xform under a rigid body and apply force on that position, that force is applied continuously. This should be soon available.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.