Joints: link offsets in b's units, new joints start inside their limits, loop dof at dead points (#1415)

joint.motion_link offset is read in the linked value's units (degrees or mm, or an expression); links are still stored in radians, so saved designs open unchanged. A new joint whose values fall outside its limits starts at the nearer limit, stores it, and says so in warnings. Loop dof also counts at a nearby pose, so a part at a dead point of its loop keeps its mobility. The mechanisms skill is updated to match.
This commit is contained in:
Mateusz Sych authored and GitHub committed 2026-10-15 12:45:48 -04:00
1 parent d0a4443939
commit c2ba3657f3
6 files changed
+270 -66

No files matched your search

+3 -2
View File
@@ -878,8 +878,9 @@ pub fn commands(app: &SolveApp, k: &Asm, inputs: &[SelInput]) -> Result<Vec<(Str
Asm::MotionLink { a, b, ia, ib, ratio, offset } => {
let js = &s.doc.assembly.joints;
let (Some(ja), Some(jb)) = (js.get(*a), js.get(*b)) else { return Err("needs two joints".into()) };
let num = |e: &str| eval(e, ValueKind::Unitless);
cmd("joint.motion_link", json!({"a": ja.id, "b": jb.id, "ia": ia, "ib": ib, "ratio": num(ratio)?, "offset": num(offset)?}))
// The offset as typed: the engine reads it in Joint 2's units (deg or mm).
let ratio = eval(ratio, ValueKind::Unitless)?;
cmd("joint.motion_link", json!({"a": ja.id, "b": jb.id, "ia": ia, "ib": ib, "ratio": ratio, "offset": offset.trim()}))
}
// The check runs from its Compute button; OK only closes.
Asm::Interference { .. } => Vec::new(),