Kernel rig: motion links, rigid groups, floating chains, named origins, edit, delete, solve, inspect, reach and sweep

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-29 17:20:41 -04:00
committed by Irakli Kourtis
parent 236a5597e8
commit d136b313a1
38 changed files with 3570 additions and 0 deletions
@@ -0,0 +1,40 @@
{
"sources": [],
"what": "a revolute between Gear and a free peg beside a grounded hinge chain",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Gear: box 10x10x10 from (60,-5,0), centre (65,0,5), on revolute G2 about z through (50,0,0), here G2 joins a free Peg (not Base) to Gear while Hinge joins Arm to grounded Base: the Peg-Gear chain reaches nothing fixed, so a drive answers moved: false and Gear stays at (65,0,5)",
"body_count": 4,
"volume_mm3": 9064.0,
"results": [
{
"step": 16,
"json": {
"moved": false
}
},
{
"step": 17,
"json": {
"total": {
"center_of_mass": [
65.0,
0.0,
5.0
]
}
}
},
{
"step": 18,
"json": {
"floating": [
{
"joints": [
"G2"
]
}
]
}
}
]
}
@@ -0,0 +1,227 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 10,
"width": 10,
"height": 10,
"corner": [
60,
-5,
0
],
"operation": "new",
"body_name": "GearBox"
}
},
{
"command": "component.create",
"params": {
"name": "Gear",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"GearBox"
],
"component": "Gear"
}
},
{
"command": "solid.box",
"params": {
"length": 4,
"width": 4,
"height": 4,
"corner": [
48,
-2,
-14
],
"operation": "new",
"body_name": "PegBox"
}
},
{
"command": "component.create",
"params": {
"name": "Peg",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"PegBox"
],
"component": "Peg"
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "G2",
"flip": true,
"a": {
"occurrence": "Peg",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Gear",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "G2",
"value": 90,
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Gear:1"
}
},
{
"command": "joint.list",
"params": {}
}
]
}
@@ -0,0 +1,29 @@
{
"sources": [],
"what": "a revolute driven 90 degrees, then deleted",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); after joint.delete the design has no joints and no links; Arm keeps the placement it had: (0,20,5)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 11,
"json": {
"joints": [],
"links": []
}
},
{
"step": 12,
"json": {
"total": {
"center_of_mass": [
0.0,
20.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,134 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 90
}
},
{
"command": "joint.delete",
"params": {
"joint": "Hinge"
}
},
{
"command": "joint.list",
"params": {}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,28 @@
{
"sources": [],
"what": "a motion link deleted, then its driver turned",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Gear: box 10x10x10 from (60,-5,0), centre (65,0,5), on revolute G2 about z through (50,0,0); link Hinge -> G2 (ratio 1) deleted (link 0): Hinge 30 leaves G2 at 0, Gear at (65,0,5)",
"body_count": 3,
"volume_mm3": 9000.0,
"results": [
{
"step": 15,
"json": {
"links": []
}
},
{
"step": 17,
"json": {
"total": {
"center_of_mass": [
65.0,
0.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,209 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 10,
"width": 10,
"height": 10,
"corner": [
60,
-5,
0
],
"operation": "new",
"body_name": "GearBox"
}
},
{
"command": "component.create",
"params": {
"name": "Gear",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"GearBox"
],
"component": "Gear"
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "G2",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Gear",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.motion_link",
"params": {
"a": "Hinge",
"b": "G2",
"ratio": 1
}
},
{
"command": "joint.delete",
"params": {
"link": 0
}
},
{
"command": "joint.list",
"params": {}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 30
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Gear:1"
}
}
]
}
@@ -0,0 +1,46 @@
{
"sources": [],
"what": "joint.edit flip: false on a revolute made with flip: true",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); frame x = +x, z = +z at the origin on both sides; unflipped, B's frame is turned by diag(1,-1,-1) in A's, a half turn about world x: (20,0,5) -> (20,0,-5)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 9,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
5.0
]
}
}
},
{
"step": 11,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
-5.0
],
"bbox": {
"min": [
0.0,
-5.0,
-10.0
],
"max": [
40.0,
5.0,
0.0
]
}
}
}
}
]
}
@@ -0,0 +1,143 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"frame": {
"origin": [
0,
0,
0
],
"z": [
0,
0,
1
],
"x": [
1,
0,
0
]
}
},
"b": {
"occurrence": "Arm",
"frame": {
"origin": [
0,
0,
0
],
"z": [
0,
0,
1
],
"x": [
1,
0,
0
]
}
},
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
},
{
"command": "joint.edit",
"params": {
"joint": "Hinge",
"flip": false
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,44 @@
{
"sources": [],
"what": "joint.edit offset 3 on a revolute",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); the offset moves B's frame 3 mm up A's z: (20,0,5) -> (20,0,8); a drive to 90 then gives (0,20,8)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 10,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
8.0
]
}
}
},
{
"step": 11,
"json": {
"values": [
{
"value": 90.0
}
]
}
},
{
"step": 12,
"json": {
"total": {
"center_of_mass": [
0.0,
20.0,
8.0
]
}
}
}
]
}
@@ -0,0 +1,137 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.edit",
"params": {
"joint": "Hinge",
"offset": 3
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 90
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,28 @@
{
"sources": [],
"what": "a suppressed revolute driven 90 degrees",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); a suppressed joint can move nothing: the drive answers moved: false and Arm stays at (20,0,5)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 10,
"json": {
"moved": false
}
},
{
"step": 11,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,131 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.edit",
"params": {
"joint": "Hinge",
"suppressed": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"value": 90,
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,58 @@
{
"sources": [],
"what": "joint.inspect of a revolute about z at (0,0,0)",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); the hinge's frames are at the origin with z up on both sides, revolute, its one value 'angle' at 0",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 9,
"json": {
"joints": [
{
"name": "Hinge",
"type": "revolute",
"flip": true,
"a": {
"occurrence_name": "Base:1",
"frame": {
"origin": [
0.0,
0.0,
0.0
],
"z": [
0.0,
0.0,
1.0
]
}
},
"b": {
"occurrence_name": "Arm:1",
"frame": {
"origin": [
0.0,
0.0,
0.0
],
"z": [
0.0,
0.0,
1.0
]
}
},
"values": [
{
"name": "angle",
"value": 0.0
}
]
}
]
}
}
]
}
@@ -0,0 +1,116 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.inspect",
"params": {
"joint": "Hinge"
}
}
]
}
@@ -0,0 +1,34 @@
{
"sources": [],
"what": "a motion link b = a into a follower limited to -20..20",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Gear: box 10x10x10 from (60,-5,0), centre (65,0,5), on revolute G2 about z through (50,0,0); b = a clamped to b's limits: Hinge 45 leaves G2 at 20: Gear centre (50 + 15 cos20, 15 sin20, 5)",
"body_count": 3,
"volume_mm3": 9000.0,
"results": [
{
"step": 15,
"json": {
"total": {
"center_of_mass": [
64.095389,
5.130302,
5.0
]
}
}
},
{
"step": 16,
"json": {
"total": {
"center_of_mass": [
14.142136,
14.142136,
5.0
]
}
}
}
]
}
@@ -0,0 +1,211 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 10,
"width": 10,
"height": 10,
"corner": [
60,
-5,
0
],
"operation": "new",
"body_name": "GearBox"
}
},
{
"command": "component.create",
"params": {
"name": "Gear",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"GearBox"
],
"component": "Gear"
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "G2",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Gear",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true,
"limits": [
[
-20,
20
]
]
}
},
{
"command": "joint.motion_link",
"params": {
"a": "Hinge",
"b": "G2",
"ratio": 1
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 45
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Gear:1"
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,22 @@
{
"sources": [],
"what": "a motion link b = 2a + 10 between two revolutes",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Gear: box 10x10x10 from (60,-5,0), centre (65,0,5), on revolute G2 about z through (50,0,0); G2 = 2\u00b7Hinge + 10 deg: Hinge 20 puts G2 at 50: Gear centre (50 + 15 cos50, 15 sin50, 5)",
"body_count": 3,
"volume_mm3": 9000.0,
"results": [
{
"step": 15,
"json": {
"total": {
"center_of_mass": [
59.641814,
11.490667,
5.0
]
}
}
}
]
}
@@ -0,0 +1,200 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 10,
"width": 10,
"height": 10,
"corner": [
60,
-5,
0
],
"operation": "new",
"body_name": "GearBox"
}
},
{
"command": "component.create",
"params": {
"name": "Gear",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"GearBox"
],
"component": "Gear"
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "G2",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Gear",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.motion_link",
"params": {
"a": "Hinge",
"b": "G2",
"ratio": 2,
"offset": 10
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 20
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Gear:1"
}
}
]
}
@@ -0,0 +1,40 @@
{
"sources": [],
"what": "a revolute between two free parts, the design's only joint",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Gear: box 10x10x10 from (60,-5,0), centre (65,0,5), on revolute G2 about z through (50,0,0), here G2 joins Arm (not Base) to Gear and no joint reaches Base: with nothing grounded involved, the first joint's A side (Arm) is fixed, so Gear turns 90 about (50,0,0): (50,15,5)",
"body_count": 3,
"volume_mm3": 9000.0,
"results": [
{
"step": 12,
"json": {
"moved": true
}
},
{
"step": 13,
"json": {
"total": {
"center_of_mass": [
50.0,
15.0,
5.0
]
}
}
},
{
"step": 14,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,162 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 10,
"width": 10,
"height": 10,
"corner": [
60,
-5,
0
],
"operation": "new",
"body_name": "GearBox"
}
},
{
"command": "component.create",
"params": {
"name": "Gear",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"GearBox"
],
"component": "Gear"
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "G2",
"flip": true,
"a": {
"occurrence": "Arm",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Gear",
"point": [
50,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "G2",
"value": 90,
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Gear:1"
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,32 @@
{
"sources": [],
"what": "a slider whose origins are the centres of two planar faces",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); a: Base's top face (centre (0,0,0), z +z); b: Arm's bottom face (centre (20,0,0), z -z); mated (no flip) the two faces meet: Arm slides 20 back along x so its bottom centre sits on (0,0,0) and turns at most about z; a slide of 3 lifts it 3 mm off the face: z centre 8, volume unchanged",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 9,
"json": {
"values": [
{
"value": 3.0
}
]
}
},
{
"step": 10,
"json": {
"total": {
"center_of_mass": [
0.0,
0.0,
8.0
]
}
}
}
]
}
@@ -0,0 +1,113 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "slider",
"name": "Lift",
"a": {
"occurrence": "Base",
"face": [
5,
5,
0
]
},
"b": {
"occurrence": "Arm",
"face": [
30,
0,
0
]
},
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "Lift",
"quiet": true,
"value": 3
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,32 @@
{
"sources": [],
"what": "a slider from a named origin on the base's top face to the arm's bottom face",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); joint.origin 'Top' is the centre of Base's top face, (0,0,0) with z up; the arm's bottom face centre (20,0,0) mates to it, so the arm slides 20 back along x and a slide of 3 lifts it to z centre 8",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 10,
"json": {
"values": [
{
"value": 3.0
}
]
}
},
{
"step": 11,
"json": {
"total": {
"center_of_mass": [
0.0,
0.0,
8.0
]
}
}
}
]
}
@@ -0,0 +1,118 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.origin",
"params": {
"name": "Top",
"occurrence": "Base",
"face": [
5,
5,
0
]
}
},
{
"command": "joint.create",
"params": {
"type": "slider",
"name": "Lift",
"a": "Top",
"b": {
"occurrence": "Arm",
"face": [
30,
0,
0
]
},
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "Lift",
"quiet": true,
"value": 3
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,32 @@
{
"sources": [],
"what": "a revolute between two named joint origins, driven 90 degrees",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); joint.origin 'Pivot A' on Base and 'Pivot B' on Arm, both at the origin with z up; the joint between them turns Arm to (0,20,5)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 11,
"json": {
"values": [
{
"value": 90.0
}
]
}
},
{
"step": 12,
"json": {
"total": {
"center_of_mass": [
0.0,
20.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,134 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.origin",
"params": {
"name": "Pivot A",
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
}
},
{
"command": "joint.origin",
"params": {
"name": "Pivot B",
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": "Pivot A",
"b": "Pivot B",
"quiet": true
}
},
{
"command": "joint.drive",
"params": {
"joint": "Hinge",
"quiet": true,
"value": 90
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,34 @@
{
"sources": [],
"what": "joint.reach asked to take the arm's tip to (0,60,5), 60 from the hinge",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); the tip moves on a circle of radius 40: the nearest it gets is (0,40,5), 20 mm short",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 9,
"json": {
"reached": false,
"error_mm": 20.0,
"point": [
0.0,
40.0,
5.0
]
}
},
{
"step": 10,
"json": {
"total": {
"center_of_mass": [
0.0,
20.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,133 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.reach",
"params": {
"occurrence": "Arm",
"at": [
40,
0,
5
],
"point": [
0,
60,
5
],
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,33 @@
{
"sources": [],
"what": "joint.reach takes the arm's tip from (40,0,5) to (0,40,5)",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); the tip turns about z through the origin at radius 40: (0,40,5) is reached at 90 degrees, error 0; Arm centre (0,20,5)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 9,
"json": {
"reached": true,
"point": [
0.0,
40.0,
5.0
]
}
},
{
"step": 10,
"json": {
"total": {
"center_of_mass": [
0.0,
20.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,133 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.reach",
"params": {
"occurrence": "Arm",
"at": [
40,
0,
5
],
"point": [
0,
40,
5
],
"quiet": true
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,29 @@
{
"sources": [],
"what": "a hinged arm moved off its joint, then joint.solve",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); the hinge at 0 places Arm at (20,0,5); joint.solve re-places it there after a move of (0,0,50)",
"body_count": 2,
"volume_mm3": 8000.0,
"results": [
{
"step": 10,
"json": {
"conflicts": [],
"errors": []
}
},
{
"step": 11,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,131 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "occurrence.move",
"params": {
"occurrence": "Arm:1",
"translate": [
0,
0,
50
]
}
},
{
"command": "joint.solve",
"params": {}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,29 @@
{
"sources": [],
"what": "joint.sweep with apply: true",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Stop: box 50x10x10 from (-10,30,0), grounded; the arm's corner (40,5) turned \u03b8 reaches y = 40 sin \u03b8 + 5 cos \u03b8, which is 30 at \u03b8 = asin(30/\u221a1625) - atan(5/40) = 40.9676; apply leaves the hinge at the stop: Arm centre (20 cos \u03b8, 20 sin \u03b8, 5)",
"body_count": 3,
"volume_mm3": 13000.0,
"results": [
{
"step": 13,
"json": {
"stopped_at": 40.966136,
"applied": true
}
},
{
"step": 14,
"json": {
"total": {
"center_of_mass": [
15.101944,
13.112257,
5.0
]
}
}
}
]
}
@@ -0,0 +1,170 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 50,
"width": 10,
"height": 10,
"corner": [
-10,
30,
0
],
"operation": "new",
"body_name": "StopBox"
}
},
{
"command": "component.create",
"params": {
"name": "Stop",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"StopBox"
],
"component": "Stop"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Stop:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.sweep",
"params": {
"joint": "Hinge",
"occurrences": [
"Arm"
],
"against": [
"Stop"
],
"apply": true,
"from": 0,
"to": 120
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}
@@ -0,0 +1,17 @@
{
"sources": [],
"what": "joint.sweep of the hinged arm from 0 to 30, short of the block",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Stop: box 50x10x10 from (-10,30,0), grounded; the arm's corner (40,5) turned \u03b8 reaches y = 40 sin \u03b8 + 5 cos \u03b8, which is 30 at \u03b8 = asin(30/\u221a1625) - atan(5/40) = 40.9676; 30 < 40.97, so nothing stops it: stopped_at and stopped_by null",
"body_count": 3,
"volume_mm3": 13000.0,
"results": [
{
"step": 13,
"json": {
"stopped_at": null,
"stopped_by": null
}
}
]
}
@@ -0,0 +1,163 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 50,
"width": 10,
"height": 10,
"corner": [
-10,
30,
0
],
"operation": "new",
"body_name": "StopBox"
}
},
{
"command": "component.create",
"params": {
"name": "Stop",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"StopBox"
],
"component": "Stop"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Stop:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.sweep",
"params": {
"joint": "Hinge",
"occurrences": [
"Arm"
],
"against": [
"Stop"
],
"from": 0,
"to": 30
}
}
]
}
@@ -0,0 +1,29 @@
{
"sources": [],
"what": "joint.sweep of the hinged arm towards a grounded block",
"source": "analytic",
"method": "Base: box 20x20x10 from (-10,-10,-10), grounded; Arm: box 40x10x10 from (0,-5,0), centre (20,0,5); Stop: box 50x10x10 from (-10,30,0), grounded; the arm's corner (40,5) turned \u03b8 reaches y = 40 sin \u03b8 + 5 cos \u03b8, which is 30 at \u03b8 = asin(30/\u221a1625) - atan(5/40) = 40.9676; the sweep from 0 to 120 stops there",
"body_count": 3,
"volume_mm3": 13000.0,
"results": [
{
"step": 13,
"json": {
"stopped_at": 40.966136,
"applied": false
}
},
{
"step": 14,
"json": {
"total": {
"center_of_mass": [
20.0,
0.0,
5.0
]
}
}
}
]
}
@@ -0,0 +1,169 @@
{
"commands": [
{
"command": "solid.box",
"params": {
"length": 20,
"width": 20,
"height": 10,
"corner": [
-10,
-10,
-10
],
"operation": "new",
"body_name": "BaseBox"
}
},
{
"command": "solid.box",
"params": {
"length": 40,
"width": 10,
"height": 10,
"corner": [
0,
-5,
0
],
"operation": "new",
"body_name": "ArmBox"
}
},
{
"command": "component.create",
"params": {
"name": "Base",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"BaseBox"
],
"component": "Base"
}
},
{
"command": "component.create",
"params": {
"name": "Arm",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"ArmBox"
],
"component": "Arm"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Base:1",
"grounded": true
}
},
{
"command": "solid.box",
"params": {
"length": 50,
"width": 10,
"height": 10,
"corner": [
-10,
30,
0
],
"operation": "new",
"body_name": "StopBox"
}
},
{
"command": "component.create",
"params": {
"name": "Stop",
"parent": "root",
"activate": false
}
},
{
"command": "component.move_bodies",
"params": {
"bodies": [
"StopBox"
],
"component": "Stop"
}
},
{
"command": "occurrence.ground",
"params": {
"occurrence": "Stop:1",
"grounded": true
}
},
{
"command": "joint.create",
"params": {
"type": "revolute",
"name": "Hinge",
"flip": true,
"a": {
"occurrence": "Base",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"b": {
"occurrence": "Arm",
"point": [
0,
0,
0
],
"z": [
0,
0,
1
]
},
"quiet": true
}
},
{
"command": "joint.sweep",
"params": {
"joint": "Hinge",
"occurrences": [
"Arm"
],
"against": [
"Stop"
],
"from": 0,
"to": 120
}
},
{
"command": "occurrence.properties",
"params": {
"occurrence": "Arm:1"
}
}
]
}