بنقرة واحدة
quaternions
Quaternion creation, component access, and Euler angle conversion in PyChrono
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Quaternion creation, component access, and Euler angle conversion in PyChrono
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Entry point for FSI-coupled hybrid plans (plan_type=fsi_in_scene) — any scene combining SPH fluid (water tanks, dam-break, wave channels) with multi-body dynamics, optionally with a wheeled vehicle. Pick this over mbs_in_scene whenever the plan involves a fluid domain (scene_objects with domain_type starting "sph_") or an FSI body registration (scene_objects with fsi_registration set). Routes to fsi/sph (always), veh/wheeled_vehicle (when vehicle present), and enforces FSI-specific invariants distinct from generic mbs_in_scene rigid scenes.
Entry point for rigid-body hybrid plans (plan_type=mbs_in_scene) combining a robot or vehicle with scene assets — NO fluid coupling. Routes to the correct domain skills and defines only high-level invariants. Use core/fsi_in_scene instead when the plan involves SPH fluid or FSI body registration.
Entry point for pure multi-body simulation plans (plan_type=mbs). Routes the agent to the correct mechanics, system, and camera skills and defines only high-level invariants.
Entry point for static scene plans (plan_type=scene). Routes the agent to the correct scene, system, and camera skills and defines only high-level invariants.
Set up SPH-based Fluid-Structure Interaction (FSI): create ChFsiFluidSystemSPH and ChFsiSystemSPH, configure fluid and SPH parameters, seed fluid particles with hydrostatic initialization, add container BCE boundary markers, register floating rigid bodies, optionally couple with a wheeled vehicle, and advance with sysFSI.DoStepDynamics(dT).
Translate a `geometry_relations` entry from the plan into correct PyChrono coordinate code. Read this whenever the plan declares a relation_name you have not previously encoded, and especially BEFORE writing SetPos / camera placement for any body that participates in a multi-body geometric constraint. Each subsection below is one canonical pattern named exactly as it appears in `plan.geometry_relations[i].relation_name`.
| name | quaternions |
| description | Quaternion creation, component access, and Euler angle conversion in PyChrono |
| compatibility | pychrono >= 8.0 |
| metadata | {"domain":"mbs"} |
Access quaternion components, create quaternions from angles/axes, and convert to Euler angles in PyChrono.
When reading body orientation, converting to Euler angles, creating a rotation, or passing a quaternion to Initialize/SetRot.
PyChrono quaternions use scalar-first storage: e0 is the scalar (w) part.
q = body.GetRot() # ChQuaterniond
# Correct attribute access:
w = q.e0 # scalar (w) component
i = q.e1 # x component
j = q.e2 # y component
k = q.e3 # z component
Do NOT use any of these — they do not exist in PyChrono:
# WRONG — AttributeError:
q.w # does not exist
q.x # does not exist
q.y # does not exist
q.z # does not exist
q.GetW() # does not exist
q.GetX() # does not exist
q.GetY() # does not exist
q.GetZ() # does not exist
rot = body.GetRot() # ChQuaterniond
euler = rot.GetCardanAnglesXYZ() # returns ChVector3d
angle_x = euler.x # rotation about X-axis [rad]
angle_y = euler.y # rotation about Y-axis [rad]
angle_z = euler.z # rotation about Z-axis [rad]
# From angle and axis (free function — returns a new quaternion):
q = chrono.QuatFromAngleAxis(angle_rad, chrono.VECT_Z)
q = chrono.QuatFromAngleAxis(angle_rad, chrono.ChVector3d(0, 0, 1))
# From angle and axis (instance method — mutates existing quaternion in-place):
q = chrono.ChQuaterniond()
q.SetFromAngleAxis(angle_rad, chrono.ChVector3d(0, 1, 0))
# Identity (no rotation):
q = chrono.QUNIT
# From Euler angles XYZ:
q = chrono.QuatFromAngleX(ax) * chrono.QuatFromAngleY(ay) * chrono.QuatFromAngleZ(az)
chrono.QUNIT # identity quaternion (no rotation)
chrono.Q_ROTATE_Y_TO_Z # rotate so Y-axis maps to Z-axis
chrono.Q_ROTATE_Y_TO_X # rotate so Y-axis maps to X-axis
chrono.Q_ROTATE_Z_TO_X # rotate so Z-axis maps to X-axis
rot = body.GetRot() # ChQuaterniond
# Body-local → world frame (e.g., attachment point on body to world position)
world_vec = rot.RotateBack(local_vec)
# World → body-local frame
local_vec = rot.Rotate(world_vec)
Typical usage — compute world position of a body-local attachment point:
rotor_pos = rotor.GetPos()
rotor_rot = rotor.GetRot()
attach_local = chrono.ChVector3d(0.25, 0, 0) # point in body frame
attach_world = rotor_pos + rotor_rot.RotateBack(attach_local)
v = chrono.ChVector3d(x, y, z)
v.Length() # magnitude (scalar)
v.Cross(other_vec) # cross product → ChVector3d
v.Dot(other_vec) # dot product → scalar
# Vector arithmetic: +, -, * (scalar) work as expected
delta = pos2 - pos1 # difference vector
rot = body.GetRot()
euler = rot.GetCardanAnglesXYZ() # ChVector3d
angle_about_z = euler.z # [rad]
q = chrono.QuatFromAngleAxis(chrono.CH_PI / 4, chrono.VECT_Z)
body.SetRot(q)
norm = (q.e0**2 + q.e1**2 + q.e2**2 + q.e3**2) ** 0.5
# Should be ~1.0 for a valid rotation quaternion
rot = chrono.QuatFromAngleAxis(-chrono.CH_PI / 2, chrono.ChVector3d(0, 1, 0))
frame = chrono.ChFramed(chrono.ChVector3d(x, y, z), rot)
joint.Initialize(body1, body2, frame)
allowed_classes:
allowed_methods:
allowed_constants:
allowed_utils: