一键导入
irrlicht
Irrlicht visualization — visual shapes (mesh, line, spring), materials, GUI overlays, path rendering, and collision debug.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Irrlicht visualization — visual shapes (mesh, line, spring), materials, GUI overlays, path rendering, and collision debug.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Quaternion creation, component access, and Euler angle conversion in PyChrono
Run the time-stepping loop, collect data, and post-process results with matplotlib or CSV.
Create rigid bodies with mass, geometry, collision shapes, and visual assets.
Enable contact detection using the correct contact material for NSC or SMC systems.
Apply custom forces/torques to rigid bodies via accumulators, and impose prescribed motion or force between two bodies using ChLinkMotor classes. Covers axis-aware force/torque application and paired internal reactions.
Create and configure a PyChrono ChSystem, gravity, contact method, and solver.
| name | irrlicht |
| description | Irrlicht visualization — visual shapes (mesh, line, spring), materials, GUI overlays, path rendering, and collision debug. |
| compatibility | pychrono >= 8.0 |
| metadata | {"domain":"visualization"} |
Cover the full Irrlicht visualization surface beyond basic window setup: loading mesh assets, custom visual materials, GUI text overlays, path/NURBS line rendering, and collision-shape debug callbacks.
When you need richer visuals than simple primitives — loading .obj/.dae mesh files,
applying textures or custom materials, drawing overlay text, rendering geometric paths, or
debugging collision shapes programmatically.
import pychrono.irrlicht as chronoirr
Do NOT use pychrono.sensor, ChSensorManager, or ChCameraSensor — those are for the
sensor module, not MBS visualization.
mbs/visualization)win_w = int # window width [px]
win_h = int # window height [px]
eye_x = float # camera x [m]
eye_y = float # camera y [m]
eye_z = float # camera z [m]
vis = chronoirr.ChVisualSystemIrrlicht()
vis.AttachSystem(sys) # 1. link physics system
vis.SetWindowSize(win_w, win_h) # 2. resolution
vis.SetWindowTitle('My Simulation') # 3. title
vis.SetCameraVertical(chrono.CameraVerticalDir_Z) # 4. match gravity axis (see below)
vis.Initialize() # 5. open window
vis.AddLogo(chrono.GetChronoDataFile('logo_chrono_alpha.png')) # 6. logo
vis.AddSkyBox() # 7. skybox
vis.AddCamera(chrono.ChVector3d(eye_x, eye_y, eye_z)) # 8. camera
vis.AddTypicalLights() # 9. lighting
SetCameraVertical)Irrlicht defaults to Y-up camera rendering. If your physics uses Z-up (gravity along -Z, ground in XY plane), the scene will appear tilted — e.g. horizontal motion looks "upward". Call vis.SetCameraVertical() before vis.Initialize() to match the physics coordinate system:
# gravity_axis="-z" or "+z" → Z-up
vis.SetCameraVertical(chrono.CameraVerticalDir_Z)
# gravity_axis="-y" or "+y" → Y-up (Irrlicht default; can omit)
vis.SetCameraVertical(chrono.CameraVerticalDir_Y)
Rule: set the vertical dir to the axis anti-parallel to gravity (gravity=-z → Z is up → CameraVerticalDir_Z).
| Target | Shape | API |
|---|---|---|
| Body | Mesh, triangle, NURBS, path | body.AddVisualShape(shape, frame) |
| Link (ChLinkTSDA) | Spring | spring.AddVisualShape(ChVisualShapeSpring(...)) |
ChVisualShapeModelFile)Use for .obj or .dae (Collada) assets from disk.
mesh_file = str # path to mesh file, e.g. chrono.GetChronoDataFile('models/forklift/body.obj')
texture_file = str # path to texture, e.g. chrono.GetChronoDataFile('textures/bluewhite.png')
offset_x = float # mesh offset x relative to body frame [m]
offset_y = float # mesh offset y relative to body frame [m]
offset_z = float # mesh offset z relative to body frame [m]
objmesh = chrono.ChVisualShapeModelFile()
objmesh.SetFilename(mesh_file)
objmesh.SetTexture(texture_file)
body.AddVisualShape(objmesh, chrono.ChFramed(chrono.ChVector3d(offset_x, offset_y, offset_z), chrono.QUNIT))
ChVisualShapeTriangleMesh)Build geometry vertex-by-vertex; attach a material for color.
v0_x = float; v0_y = float; v0_z = float # triangle vertex 0 [m]
v1_x = float; v1_y = float; v1_z = float # triangle vertex 1 [m]
v2_x = float; v2_y = float; v2_z = float # triangle vertex 2 [m]
offset_x = float # shape offset x [m]
offset_y = float # shape offset y [m]
offset_z = float # shape offset z [m]
mesh = chrono.ChVisualShapeTriangleMesh()
mesh.GetMesh().AddTriangle(
chrono.ChVector3d(v0_x, v0_y, v0_z),
chrono.ChVector3d(v1_x, v1_y, v1_z),
chrono.ChVector3d(v2_x, v2_y, v2_z))
mesh.AddMaterial(some_material) # optional
body.AddVisualShape(mesh, chrono.ChFramed(chrono.ChVector3d(offset_x, offset_y, offset_z), chrono.QUNIT))
ChVisualShapeLine + ChLineNurbs)nurbs_order = int # polynomial order (e.g. 3 = cubic)
cp1_x = float; cp1_y = float; cp1_z = float # control point 1 [m]
cp2_x = float; cp2_y = float; cp2_z = float # control point 2 [m]
cp3_x = float; cp3_y = float; cp3_z = float # control point 3 [m]
cp4_x = float; cp4_y = float; cp4_z = float # control point 4 [m]
nurbs = chrono.ChLineNurbs()
v1 = chrono.ChVector3d(cp1_x, cp1_y, cp1_z)
v2 = chrono.ChVector3d(cp2_x, cp2_y, cp2_z)
v3 = chrono.ChVector3d(cp3_x, cp3_y, cp3_z)
v4 = chrono.ChVector3d(cp4_x, cp4_y, cp4_z)
control_pts = chrono.vector_ChVector3d([v1, v2, v3, v4])
nurbs.Setup(nurbs_order, control_pts)
nurbs_asset = chrono.ChVisualShapeLine()
nurbs_asset.SetLineGeometry(nurbs)
body.AddVisualShape(nurbs_asset)
ChVisualShapeLine + ChLinePath)Combine segments and arcs into a single closed or open path.
seg1_ax = float; seg1_ay = float; seg1_az = float # segment 1 start [m]
seg1_bx = float; seg1_by = float; seg1_bz = float # segment 1 end [m]
arc1_cx = float; arc1_cy = float; arc1_cz = float # arc 1 centre [m]
arc1_r = float # arc 1 radius [m]
seg2_ax = float; seg2_ay = float; seg2_az = float # segment 2 start [m]
seg2_bx = float; seg2_by = float; seg2_bz = float # segment 2 end [m]
arc2_cx = float; arc2_cy = float; arc2_cz = float # arc 2 centre [m]
arc2_r = float # arc 2 radius [m]
mpath = chrono.ChLinePath()
seg1 = chrono.ChLineSegment(
chrono.ChVector3d(seg1_ax, seg1_ay, seg1_az),
chrono.ChVector3d(seg1_bx, seg1_by, seg1_bz))
arc1 = chrono.ChLineArc(
chrono.ChCoordsysd(chrono.ChVector3d(arc1_cx, arc1_cy, arc1_cz)),
arc1_r,
-chrono.CH_PI_2, # start angle [rad]
chrono.CH_PI_2, # end angle [rad]
True) # counterclockwise
seg2 = chrono.ChLineSegment(
chrono.ChVector3d(seg2_ax, seg2_ay, seg2_az),
chrono.ChVector3d(seg2_bx, seg2_by, seg2_bz))
arc2 = chrono.ChLineArc(
chrono.ChCoordsysd(chrono.ChVector3d(arc2_cx, arc2_cy, arc2_cz)),
arc2_r, chrono.CH_PI_2, -chrono.CH_PI_2, True)
mpath.AddSubLine(seg1)
mpath.AddSubLine(arc1)
mpath.AddSubLine(seg2)
mpath.AddSubLine(arc2)
mpath.SetClosed(True) # join last point back to first
path_asset = chrono.ChVisualShapeLine()
path_asset.SetLineGeometry(mpath)
body.AddVisualShape(path_asset)
ChVisualShapeSpring)Use for ChLinkTSDA (translational spring-damper-actuator) links. The spring visual is attached to the link, not to a body. It automatically updates between the two connected points as the simulation runs.
coil_radius = float # coil radius [m], e.g. 0.02–0.05
resolution = int # rendering resolution, e.g. 65–80
turns = float # number of coil turns, e.g. 10–15
spring = chrono.ChLinkTSDA()
spring.Initialize(body1, body2, True,
chrono.ChVector3d(0, 0, 0),
chrono.ChVector3d(0, 0, 0))
spring.SetRestLength(rest_length)
spring.SetSpringCoefficient(k)
spring.SetDampingCoefficient(c)
sys.AddLink(spring)
# Attach visual to the link (not to body)
spring.AddVisualShape(chrono.ChVisualShapeSpring(coil_radius, resolution, turns))
Optional color:
vis = chrono.ChVisualShapeSpring(0.02, 65, 10)
vis.SetColor(chrono.ChColor(0.2, 0.6, 0.9))
spring.AddVisualShape(vis)
Rule: Do not share one ChVisualShapeSpring instance across multiple links — create a separate instance per spring.
ChVisualMaterial)Create a shared material and apply it to one or more shapes.
r = float # red channel [0, 1]
g = float # green channel [0, 1]
b = float # blue channel [0, 1]
texture_file = str # path to texture image
mat = chrono.ChVisualMaterial()
mat.SetDiffuseColor(chrono.ChColor(r, g, b))
mat.SetKdTexture(texture_file)
shape.AddMaterial(mat) # attach to any ChVisualShape
Shortcut for solid color (no texture):
r = float # red [0, 1]
g = float # green [0, 1]
b = float # blue [0, 1]
shape.SetColor(chrono.ChColor(r, g, b))
Call between BeginScene() and EndScene() every frame.
overlay_x1 = int # left edge [px]
overlay_y1 = int # top edge [px]
overlay_x2 = int # right edge [px]
overlay_y2 = int # bottom edge [px]
while vis.Run():
vis.BeginScene()
vis.Render()
vis.GetGUIEnvironment().addStaticText(
'Hello World!',
chronoirr.recti(overlay_x1, overlay_y1, overlay_x2, overlay_y2))
vis.EndScene()
sys.DoStepDynamics(dt)
addStaticText redraws on every call, so place it inside the loop to keep the text live.
Subclass chrono.VisualizationCallback to receive line-draw calls that describe collision
shape boundaries.
class DebugDrawer(chrono.VisualizationCallback):
def __init__(self):
super().__init__()
def DrawLine(self, pA, pB, color):
# pA, pB are ChVector3d endpoints; color is ChColor
print(f" A=({pA.x:.3f}, {pA.y:.3f}, {pA.z:.3f})"
f" B=({pB.x:.3f}, {pB.y:.3f}, {pB.z:.3f})")
drawer = DebugDrawer()
sys.GetCollisionSystem().RegisterVisualizationCallback(drawer)
while vis.Run():
vis.BeginScene()
vis.Render()
vis.EndScene()
sys.DoStepDynamics(dt)
sys.GetCollisionSystem().Visualize(chrono.ChCollisionSystem.VIS_Shapes)
Visualize() triggers DrawLine for every collision shape boundary in the scene.
While the simulation window is open, press **i** to open the Irrlicht debug panel, then
tick "Draw Collision Shapes" to overlay collision wireframes without writing any callback.