datetime:2025/01/10 14:45
author:nzb

该项目来源于mujoco_learning

作用力

平动

旋转

外部力

我们查看文档计算部分可以看到有 qfrc_passive,qfrc_actuator,qfrc_applied 三个力分别对应被动力,驱动力,外部力,nv是自由度

只要看手册的api或者头文件中,找到 mj_applyFT 函数应用外部力。

或者还可以使用 xfrc_applied 直接作用外部力在质心上。

这里也说明了是笛卡尔力。

   mj_applyFT 函数的参数,是三维的力,三维扭矩,三维坐标( worldbody 坐标系), bodyidqfrc_target 可以直接使用 d->qfrc_appliedmj_applyFT 是对于 body“自由度” 上施加力。于是我们可以使用两个方式对body施加外部力。
   qfrc_target 还可以是以下这些被动力等 qfrc_xxx 的力

mj_Data接口演示(作用在质心上):

int bullet_id = mj_name2id(m, mjOBJ_BODY, "box");
mjtNum *set_torque = d->xfrc_applied + bullet_id * 6;

mj_applyFT函数接口演示(可以调整施力点):

int bullet_id = mj_name2id(m, mjOBJ_BODY, "box");
mjtNum force[3] = {0.0, 0.0, 9.81};
mjtNum torque[3] = {0.0, 0.0, 0.0};
mjtNum point[3] = {0.0, 0.0, 0.0}; 
mj_applyFT(m, d, force, torque, point, id, d->qfrc_applied);

mj_applyFT每次调用都是增量式,如果我们想清除力可以使用mju_zero,如mju_zero(d->qfrc_applied, m->nv);

驱动力

  mjData.qfrc_actuator是驱动器执行的力,不同驱动器最终会计算出力或者扭矩作用到关节上。

被动力

   mjData.qfrc_passive 是被动力,关节参数的 damping,stiffness,摩擦力,流体阻力都会最终计算到该力中。

约束力

   mjData.efc_force 是约束力,关节的 frictionloss,equality 计算出来的合力为改力。

  jar = Jac*qacc-aref 残差=雅可比*关节加速度-参考伪加速度

源码实现(SRC/engine/engine_core_constraint.c)

偏置力

  mjData.qfrc_bias科里奥利力等,由引擎自动计算。

代码

import time
import mujoco
import mujoco.viewer

m = mujoco.MjModel.from_xml_path('../../API-MJCF/force.xml')
d = mujoco.MjData(m)

mujoco.mj_step(m, d)
'''--------box--------'''
box_id = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_BODY, "box")
box_force = [0.0, 0.0, 0.1]
box_torque = [0.0, 0.0, 0.0]
box_point = [0.0, 0.0, 0.0]
red_point = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_SITE, "red_point")
point = d.site_xpos[red_point]
# mujoco.mj_applyFT(m, d, box_force, box_torque, box_point, box_id, d.qfrc_applied)
'''--------box--------'''

'''--------力——加速度--------'''
sphere_id = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_BODY, "sphere")
sphere_force = [0.0, 0.0, 0.0]
sphere_torque = [0.0, 0.0, 0.0]
sphere_point = [0.0, 0.0, 0.0]
# mujoco.mj_applyFT(m, d, sphere_force, sphere_torque, sphere_point, sphere_id, d.qfrc_applied)
'''--------力——加速度--------'''

'''--------扭矩--------'''
pointer_id = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_BODY, "pointer")
pointer_force = [0.0, 0.0, 0.0]
pointer_torque = [0.0, 0.0, 0.0]
pointer_point = [0.0, 0.0, 0.0]
# mujoco.mj_applyFT(m, d, pointer_force, pointer_torque, pointer_point, pointer_id, d.qfrc_applied)
'''--------扭矩--------'''

with mujoco.viewer.launch_passive(m, d) as viewer:
  start = time.time()
  while viewer.is_running() and time.time() - start < 30:
    step_start = time.time()

    '''--------box--------'''
    # d.qfrc_applied[:] = 0  # // 清空施加的力,否则会累加
    # mujoco.mj_applyFT(m, d, box_force, box_torque, point, box_id, d.qfrc_applied)
    # mujoco.mj_step(m, d)
    '''--------box--------'''

    '''--------box--------'''
    # box_xfrc_applied = d.xfrc_applied[box_id]
    # box_xfrc_applied[0] = 0.0 # fx
    # box_xfrc_applied[1] = 0.0 # fy
    # box_xfrc_applied[2] = 9.82 # fz 缓慢上升
    # box_xfrc_applied[3] = 0.0 # tx
    # box_xfrc_applied[4] = 0.0 # ty
    # box_xfrc_applied[5] = 0.0 # tz
    # mujoco.mj_step(m, d)
    '''--------box--------'''

    '''--------力——加速度--------'''
    # d.ctrl[0] = 0.6
    # sphere_xfrc_applied = d.xfrc_applied[sphere_id]
    # sphere_xfrc_applied[0] = 0.0 # fx
    # sphere_xfrc_applied[1] = 0.0 # fy
    # sphere_xfrc_applied[2] = 0.0 # fz
    # sphere_xfrc_applied[3] = 0.0 # tx
    # sphere_xfrc_applied[4] = 0.0 # ty
    # sphere_xfrc_applied[5] = 0.0 # tz
    # mujoco.mj_step(m, d)
    # print("qfrc_passive:%f  qfrc_actuator:%f  qfrc_applied:%f qfrc_bias:%f  efc_force:%f" % (
    # d.qfrc_passive[0], d.qfrc_actuator[0], d.qfrc_applied[0], d.qfrc_bias[0], d.efc_force[0]))
    # print("lin_acc:",d.sensor("lin_acc").data[0])
    # acc = (d.qfrc_passive[0] + d.qfrc_actuator[0] +
    #        d.qfrc_applied[0] + d.qfrc_bias[0] + d.efc_force[0]) / m.body_mass[sphere_id] # 合力 / 质量 = 加速度
    # print("计算加速度:",acc)
    # frictionloss = 0.0 , 是约束力
    # # stiffness = 0.0, damping = 1.0, qfrc_passive == lin_vel
    # print("lin_vel:",d.sensor("lin_vel").data[0])
    # # stiffness = 1.0, damping = 0.0, qfrc_passive == lin_pos
    # print("lin_pos:",d.sensor("lin_pos").data[0])
    '''--------力——加速度--------'''

    '''--------扭矩--------'''
    d.ctrl[1] = 0.6
    pointer_xfrc_applied = d.xfrc_applied[pointer_id]
    pointer_xfrc_applied[0] = 0.0 # fx
    pointer_xfrc_applied[1] = 0.0 # fy
    pointer_xfrc_applied[2] = 0.0 # fz
    pointer_xfrc_applied[3] = 0.0 # tx
    pointer_xfrc_applied[4] = 0.0 # ty
    pointer_xfrc_applied[5] = 0.0 # tz
    mujoco.mj_step(m, d)
    print("qfrc_passive:%f  qfrc_actuator:%f  qfrc_applied:%f qfrc_bias:%f  efc_force:%f" % (
      d.qfrc_passive[1], d.qfrc_actuator[1], d.qfrc_applied[1], d.qfrc_bias[1], d.efc_force[1]))
    tau = d.qfrc_passive[1] + d.qfrc_actuator[1] + d.qfrc_applied[1] + d.qfrc_bias[1] + d.efc_force[1]
    print("计算扭矩:",tau)
    print("测量扭矩:",d.sensor("torque").data)
    print("pivot_pos:",d.sensor("pivot_pos").data)
    print("pivot_vel:",d.sensor("pivot_vel").data)
    '''--------扭矩--------'''


    # Example modification of a viewer option: toggle contact points every two seconds.
    with viewer.lock():
      viewer.opt.flags[mujoco.mjtVisFlag.mjVIS_CONTACTPOINT] = int(d.time % 2)

    # Pick up changes to the physics state, apply perturbations, update options from GUI.
    viewer.sync()

    # Rudimentary time keeping, will drift relative to wall clock.
    time_until_next_step = m.opt.timestep - (time.time() - step_start)
    if time_until_next_step > 0:
      time.sleep(time_until_next_step)
<mujoco>
    <compiler angle="radian" meshdir="meshes" autolimits="true" />
    <!-- density="1.225" viscosity="1.8e-5" -->
    <option timestep="0.002" gravity="0 0 -9.81" integrator="implicitfast" />
    <asset>
        <mesh name="tetrahedron" vertex="0 0 0 1 0 0 0 1 0 0 0 1" />
        <texture type="skybox" file="../MJCF/asset/desert.png"
            gridsize="3 4" gridlayout=".U..LFRB.D.." />
        <texture name="plane" type="2d" builtin="checker" rgb1=".1 .1 .1" rgb2=".9 .9 .9"
            width="512" height="512" mark="cross" markrgb=".8 .8 .8" />
        <material name="plane" reflectance="0.3" texture="plane" texrepeat="1 1" texuniform="true" />
    </asset>

    <worldbody>
        <geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="plane"
            condim="3" />
        <light directional="true" ambient=".3 .3 .3" pos="30 30 30" dir="0 -.5 -1"
            diffuse=".5 .5 .5" specular=".5 .5 .5" />

        <site type="ellipsoid" pos="0 1 0.2" size="10 0.01 0.01" rgba=".7 .7 .7 1" />
        <body name="sphere" pos="0 1 0.2">
            <joint name="lin_jnt" type="slide" axis="1 0 0" range="-10 10" damping="0.0"
                frictionloss="0.1" stiffness="1.0" />
            <geom type="sphere" mass="1" size="0.1" rgba=".2 .6 .6 1" />
        </body>

        <body name="base" pos="0 0 0">
            <geom type="cylinder" mass="100" size="0.05 0.5" rgba=".2 .2 .2 1" />
            <body name="pointer" pos="0 0 0.55">
                <joint type="hinge" name="pivot" axis="0 0 1" damping="0.0"
                    frictionloss="0.1" stiffness="0.0" />
                <site name="force_torque" size="0.01" rgba="0 1 0 1" />
                <geom type="capsule" mass="0.1" fromto="0 0 0 0.2 0 0" size="0.01"
                    rgba="0.8 0.2 0.2 0.5" />
            </body>
        </body>

        <body name="box" pos="1 0 0.2">
            <freejoint />
            <geom type="box" mass="1" size="0.1 0.1 0.1" rgba=".5 .4 .3 .5" />
            <site name="red_point" pos="0.1 0.1 0.1" rgba="1 0 0 .8" size="0.01"/>
        </body>
    </worldbody>

    <actuator>
        <motor name="lin_force" joint="lin_jnt" gear="1" />
        <motor name="motor" joint="pivot" gear="1" />
    </actuator>

    <sensor>
        <framelinacc name="lin_acc" objtype="body" objname="sphere" />
        <framelinvel name="lin_vel" objtype="body" objname="sphere" />
        <framepos name="lin_pos" objtype="body" objname="sphere" />
        <jointpos joint="pivot" name="pivot_pos"/>
        <jointvel joint="pivot" name="pivot_vel"/>
        <force name="force" site="force_torque" />
        <torque name="torque" site="force_torque" />
    </sensor>

</mujoco>

results matching ""

    No results matching ""