一键导入
openscad-integration
Use when creating URDF or Xacro files which require non-trivial geometry
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when creating URDF or Xacro files which require non-trivial geometry
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use this skill when modifying OpenSCAD files where the user wants to use the customizer features (parameter parsing, UI generation, and conversion to STL/SVG/GLB with parameter overrides).
Use this skill when modifying OpenSCAD files (*.scad)
Discover, recommend, and install OpenSCAD libraries for your projects. Use when: needing geometry functions, seeking existing modules before creating, managing library dependencies, or exploring what libraries are available in your workspace.
Core URDF/Xacro syntax, joint types, kinematic structures, and URDF validation for robot descriptions
Guide for creating appropriate geometry in URDF files - basic shapes vs OpenSCAD vs mesh files
Convert URDF files to Xacro format with macros for reusable components like wheels, sensors, and repeated geometry
| name | openscad-integration |
| description | Use when creating URDF or Xacro files which require non-trivial geometry |
This skill guides the creation and use of OpenSCAD files for custom 3D geometry in URDF robot descriptions.
Use OpenSCAD when:
CRITICAL: Always take a screenshot after creating or modifying OpenSCAD files to verify the generated geometry renders correctly. OpenSCAD syntax errors or invalid geometry will cause rendering failures. Use the MCP take_screenshot tool after save to confirm:
If the screenshot times out or shows errors, check the OpenSCAD code for syntax issues.
Before creating OpenSCAD files, ask the user:
Always ask: "I can create an OpenSCAD file to generate this geometry. It will be automatically converted to STL. Would you like me to do that?"
OpenSCAD is a script-based 3D CAD modeler:
.scad file in your project.stl when saved.stl file in your URDF.scad changesFile watching: The extension monitors .scad files and regenerates STL on save.
// Cube
cube([width, depth, height]);
cube([10, 20, 30]); // 10mm × 20mm × 30mm box
// Sphere
sphere(radius);
sphere(r=15); // 15mm radius sphere
// Cylinder
cylinder(h=height, r=radius);
cylinder(h=50, r=10); // 50mm tall, 10mm radius
// Cylinder with different top/bottom radii (cone)
cylinder(h=30, r1=15, r2=5);
// Translate (move)
translate([x, y, z])
cube([10, 10, 10]);
// Rotate (in degrees)
rotate([rx, ry, rz])
cylinder(h=20, r=5);
// Scale
scale([sx, sy, sz])
sphere(r=10);
// Combine transformations
translate([0, 0, 10])
rotate([0, 90, 0])
cylinder(h=30, r=5);
// Union (combine shapes) - default behavior
union() {
cube([20, 20, 20]);
translate([10, 10, 10])
sphere(r=12);
}
// Difference (subtract)
difference() {
cube([30, 30, 30]); // Main shape
translate([15, 15, 0]) // Subtract this
cylinder(h=30, r=8);
}
// Intersection (only overlapping parts)
intersection() {
cube([20, 20, 20]);
sphere(r=15);
}
// Define a reusable module
module bracket(width, height, thickness) {
difference() {
cube([width, height, thickness]);
// Mounting holes
translate([5, height/2, 0])
cylinder(h=thickness, r=2);
translate([width-5, height/2, 0])
cylinder(h=thickness, r=2);
}
}
// Use the module
bracket(50, 30, 5);
bracket(width=60, height=40, thickness=8);
// wheel_tread.scad
module wheel_with_tread(radius=50, width=30, tread_depth=3, tread_count=12) {
difference() {
// Main wheel body
cylinder(h=width, r=radius, center=true);
// Tread grooves
for (i = [0:tread_count-1]) {
rotate([0, 0, i * 360/tread_count])
translate([radius - tread_depth/2, 0, 0])
cube([tread_depth, 3, width+1], center=true);
}
}
}
// Generate wheel
wheel_with_tread(radius=100, width=40, tread_depth=5, tread_count=16);
URDF reference:
<link name="wheel">
<visual>
<geometry>
<!-- Extension auto-converts wheel_tread.scad to wheel_tread.stl -->
<mesh filename="package://my_robot/meshes/wheel_tread.stl" scale="0.001 0.001 0.001"/>
</geometry>
</visual>
</link>
// gripper_finger.scad
module gripper_finger(length=60, width=15, thickness=8) {
difference() {
// Main finger body
hull() {
cube([thickness, width, thickness]);
translate([length-10, 0, 0])
cube([10, width, thickness]);
}
// Grip texture (small bumps)
for (i = [10:10:length-15]) {
translate([i, width/2, thickness])
sphere(r=2);
}
}
}
gripper_finger(length=70, width=18, thickness=10);
// sensor_housing.scad
module sensor_housing(sensor_diameter=20, wall_thickness=3) {
difference() {
// Outer shell
cylinder(h=30, r=sensor_diameter/2 + wall_thickness);
// Inner cavity for sensor
translate([0, 0, wall_thickness])
cylinder(h=25, r=sensor_diameter/2);
// Mounting holes
for (angle = [0:90:270]) {
rotate([0, 0, angle])
translate([sensor_diameter/2 + wall_thickness/2, 0, 15])
rotate([90, 0, 0])
cylinder(h=wall_thickness+2, r=2);
}
}
}
sensor_housing(sensor_diameter=25, wall_thickness=4);
// mounting_bracket.scad
module l_bracket(width=50, height=40, depth=30, thickness=5) {
union() {
// Vertical plate
cube([thickness, depth, height]);
// Horizontal plate
cube([width, depth, thickness]);
// Reinforcement gusset
hull() {
translate([0, depth/2, 0])
cube([thickness, 1, thickness]);
translate([0, depth/2, height-thickness])
cube([thickness, 1, 1]);
}
}
}
l_bracket(width=60, height=50, depth=35, thickness=6);
Before writing custom code, check what's available:
The extension automatically loads libraries from:
~/.local/share/OpenSCAD/libraries~/Documents/OpenSCAD/libraries%USERPROFILE%\Documents\OpenSCAD\librariesurdf-editor.OpenSCADLibraryPaths settinginclude <MCAD/motors.scad>
use <MCAD/gears.scad>
use <MCAD/bearing.scad>
// Standard stepper motor
stepper_motor_mount(28);
// Spur gear
gear(number_of_teeth=20,
circular_pitch=5,
gear_thickness=5,
rim_thickness=5);
include <BOSL2/std.scad>
// Rounded box
cuboid([50, 30, 20], rounding=5);
// Threaded rod
threaded_rod(d=10, l=50, pitch=2);
// Grid of holes
grid_copies(spacing=20, n=3)
cylinder(h=10, r=3);
// include: Makes everything available (variables, modules)
include <MCAD/motors.scad>
// use: Only makes modules available (not variables)
use <MCAD/gears.scad>
Best practice: Use use unless you need the library's variables.
Recommended structure:
my_robot/
├── urdf/
│ └── robot.urdf.xacro
├── meshes/
│ ├── wheel.scad ← OpenSCAD source
│ ├── wheel.stl ← Auto-generated
│ ├── gripper.scad
│ └── gripper.stl
└── scad/ ← Optional: keep .scad separate
└── library.scad
meshes/ directory.stl<link name="custom_part">
<visual>
<geometry>
<mesh filename="package://my_robot/meshes/wheel.stl"/>
</geometry>
</visual>
</link>
Important: OpenSCAD typically uses millimeters, URDF uses meters.
<!-- Scale from mm to m (divide by 1000) -->
<mesh filename="package://my_robot/meshes/part.stl"
scale="0.001 0.001 0.001"/>
Tip: Document units in your .scad file:
// Units: millimeters
// This will be scaled to meters in URDF (scale="0.001 0.001 0.001")
module wheel(diameter=100) { // 100mm = 0.1m
cylinder(h=40, r=diameter/2);
}
Create families of related parts:
// parametric_wheel.scad
// Parameters can be overridden when including this file
wheel_diameter = 100; // mm
wheel_width = 40; // mm
hub_diameter = 20; // mm
spoke_count = 5;
module parametric_wheel() {
difference() {
// Rim
cylinder(h=wheel_width, r=wheel_diameter/2, center=true);
// Hub cavity
cylinder(h=wheel_width+2, r=hub_diameter/2, center=true);
// Spokes (material removal between spokes)
for (i = [0:spoke_count-1]) {
rotate([0, 0, i * 360/spoke_count + 360/(2*spoke_count)])
translate([hub_diameter/2 + (wheel_diameter-hub_diameter)/4, 0, 0])
cube([wheel_diameter/2, 5, wheel_width+2], center=true);
}
}
}
parametric_wheel();
Use animation to verify moving parts:
// Animate to test range of motion
$fn = 50; // Resolution
module articulated_part(angle=0) {
// Base
cube([50, 30, 10]);
// Moving part
translate([25, 15, 10])
rotate([angle, 0, 0])
translate([0, 0, 20])
cube([20, 10, 40], center=true);
}
// Use $t for animation (0 to 1)
articulated_part(angle=$t * 180 - 90);
// $fn controls circle resolution
$fn = 100; // High quality (slower)
// $fn = 30; // Medium (default-ish)
// $fn = 12; // Low quality (faster)
cylinder(h=10, r=5); // Uses $fn setting
// Override for specific shapes
cylinder(h=10, r=5, $fn=6); // Hexagon
✅ Take screenshots immediately after creating/modifying .scad files to verify rendering
✅ Ask permission before creating OpenSCAD files
✅ Use descriptive module names and parameters
✅ Add comments explaining what the code does
✅ Define dimensions as variables/parameters
✅ Document units (mm vs m) in comments
✅ Check for available libraries before writing from scratch
✅ Test with preview after creating/modifying
✅ Keep .scad files in version control
✅ Use MCP take_screenshot tool to validate geometry after every change
❌ Skip screenshot verification - geometry errors won't be caught ❌ Create overly complex geometry (affects preview performance) ❌ Forget to scale from mm to m in URDF ❌ Hardcode dimensions (use parameters instead) ❌ Create .scad files for simple shapes (use URDF primitives) ❌ Ignore available libraries (don't reinvent the wheel) ❌ Mix .scad logic with URDF structure
urdf-editor.OpenSCADLibraryPathsUser: "I need a wheel with 12 spokes for my robot"
Agent:
Basic cylinder geometry won't give you spokes. I can create an
OpenSCAD file to generate a wheel with spokes. This will:
- Create a parametric wheel design
- Auto-generate STL on save
- Allow easy dimension changes
Would you like me to create this?
After approval:
// meshes/spoke_wheel.scad
// Units: millimeters (scale by 0.001 in URDF)
module spoke_wheel(diameter=100, width=30, hub=20, spokes=12, spoke_thickness=3) {
difference() {
union() {
// Rim
cylinder(h=width, r=diameter/2, center=true);
// Hub
cylinder(h=width, r=hub/2, center=true);
// Spokes
for (i = [0:spokes-1]) {
rotate([0, 0, i * 360/spokes])
translate([hub/2, 0, 0])
cube([(diameter-hub)/2, spoke_thickness, width], center=true);
}
}
// Center hole
cylinder(h=width+2, r=hub/4, center=true);
}
}
spoke_wheel(diameter=100, width=30, hub=20, spokes=12);
<!-- In URDF -->
<link name="wheel">
<visual>
<geometry>
<mesh filename="package://my_robot/meshes/spoke_wheel.stl"
scale="0.001 0.001 0.001"/>
</geometry>
<material name="wheel_color">
<color rgba="0.2 0.2 0.2 1"/>
</material>
</visual>
</link>
OpenSCAD integration provides:
Remember: Always ask before creating OpenSCAD files, check for existing libraries first, and test with preview!