Skip to content

Commit c91232c

Browse files
committed
Align bucket pivot and lugs with arm tip, update offsets
Added BUCKET_PIVOT_Y_OFFSET to shift the bucket and lugs for proper alignment with the arm tip pin hole. Updated kinematic and visual parameters in lifetrac_v25_params.scad and lifetrac_v25.scad to use this offset, ensuring the lug back is flush with the bucket back plate as specified in DESIGN_RULES.md. Added verification code for bucket position at ground contact and clarified parameter usage for visual vs. kinematic arm leg length.
1 parent 6b576a6 commit c91232c

File tree

3 files changed

+73
-20
lines changed

3 files changed

+73
-20
lines changed

LifeTrac-v25/mechanical_design/DESIGN_RULES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This document establishes the non-negotiable geometric rules and parametric cons
1616
* **Crash Prevention**: The solver must prioritize the Target Point, but validity checks must ensure the arm tip material (steel extending below the pivot) does not crash into the ground before the bucket does.
1717

1818
## 3. Physical Component Alignment
19+
* **Lug Flush Mounting**: The back (base) of any U-channel lug or mounting bracket must be flush with the surface it is intended to be mounted to. For bucket pivot lugs, the lug back must be flush with the back plate of the bucket. No overlap or gap between lug base and mounting surface.
1920
* **Matching Tip Radii**: The radius of the Loader Arm Tip (`boss_r` in `arm_plate.scad`) must visually and dimensionally match the Bucket Pivot Lugs to ensure a clean hinge assembly.
2021
* Constraint: `boss_r` == `PIVOT_HOLE_X_FROM_FRONT`.
2122
* **Hole Alignment**: The physical hole cut into the *Arm Plate* must strictly match the kinematic point `_T`.

LifeTrac-v25/mechanical_design/openscad/lifetrac_v25.scad

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,15 +362,16 @@ function bucket_cyl_length(arm_angle, bucket_tilt) =
362362
// Bucket attachment (in bucket local, tilt about arm tip, then arm rotation)
363363
// Must match the translation in bucket_attachment
364364
// Bucket is at Y = BUCKET_LUG_OFFSET. Cylinder Lug is on back plate.
365-
// Assuming Cylinder Lug is also rotated to point backwards, Pivot is at Y=0 relative to Arm Tip?
366-
// Let's assume Cylinder Lug Pivot is at Y = 0 for now (flush with Arm Pivot Y)
365+
// BUCKET_PIVOT_Y_OFFSET shifts the entire bucket pivot assembly toward/away from arms
366+
// Cylinder Lug Pivot is at Y=0 relative to the shifted bucket pivot
367367
bucket_local_y = 0,
368368
bucket_local_z = BUCKET_CYL_MOUNT_Z_OFFSET + (BUCKET_HEIGHT - BUCKET_PIVOT_HEIGHT_FROM_BOTTOM),
369369
// Tilt about bucket pivot (at arm tip)
370370
bucket_tilted_y = bucket_local_y * cos(bucket_tilt) - bucket_local_z * sin(bucket_tilt),
371371
bucket_tilted_z = bucket_local_y * sin(bucket_tilt) + bucket_local_z * cos(bucket_tilt),
372372
// Add arm length to get position relative to arm pivot
373-
bucket_arm_y = ARM_TIP_X + bucket_tilted_y,
373+
// Include BUCKET_PIVOT_Y_OFFSET to match bucket_attachment positioning
374+
bucket_arm_y = ARM_TIP_X + BUCKET_PIVOT_Y_OFFSET + bucket_tilted_y,
374375
bucket_arm_z = ARM_TIP_Z + bucket_tilted_z,
375376
// Rotate by arm angle
376377
bucket_y = bucket_arm_y * cos(arm_angle) - bucket_arm_z * sin(arm_angle),
@@ -468,6 +469,24 @@ echo("Stroke with margin:", BUCKET_CYL_STROKE_WITH_MARGIN, "mm");
468469
echo("SELECTED BUCKET CYLINDER STROKE:", BUCKET_CYLINDER_STROKE, "mm");
469470
echo("Recommended closed length:", BUCKET_CYL_CLOSED_LENGTH, "mm");
470471

472+
// =============================================================================
473+
// BUCKET POSITION VERIFICATION (at $t=0, arms at ground)
474+
// =============================================================================
475+
// Verify bucket bottom touches ground when arms are lowered and bucket is flat
476+
_bucket_pivot_z_target = BUCKET_PIVOT_HEIGHT_FROM_BOTTOM + BUCKET_GROUND_CLEARANCE; // 90mm
477+
_bucket_translation_z = BUCKET_HEIGHT - BUCKET_PIVOT_HEIGHT_FROM_BOTTOM + BUCKET_BODY_Z_OFFSET + BUCKET_VISUAL_Z_OFFSET;
478+
_bucket_bottom_offset_from_pivot = _bucket_translation_z - BUCKET_HEIGHT; // Should equal -BUCKET_PIVOT_HEIGHT_FROM_BOTTOM
479+
_bucket_bottom_world_z = _bucket_pivot_z_target + _bucket_bottom_offset_from_pivot; // Should be 0 for flat on ground
480+
481+
echo("=== BUCKET POSITION VERIFICATION ===");
482+
echo("BUCKET_PIVOT_Z_TARGET (arm tip at ground) =", _bucket_pivot_z_target, "mm");
483+
echo("BUCKET_HEIGHT =", BUCKET_HEIGHT, "mm");
484+
echo("BUCKET_PIVOT_HEIGHT_FROM_BOTTOM =", BUCKET_PIVOT_HEIGHT_FROM_BOTTOM, "mm");
485+
echo("BUCKET_VISUAL_Z_OFFSET =", BUCKET_VISUAL_Z_OFFSET, "mm");
486+
echo("Bucket translation Z =", _bucket_translation_z, "mm");
487+
echo("Bucket bottom offset from pivot =", _bucket_bottom_offset_from_pivot, "mm");
488+
echo("BUCKET BOTTOM WORLD Z (should be 0) =", _bucket_bottom_world_z, "mm");
489+
471490
// =============================================================================
472491
// LIFTING CAPACITY CALCULATIONS
473492
// =============================================================================
@@ -2301,9 +2320,10 @@ module bucket_attachment() {
23012320
if (show_bucket) {
23022321
translate([0, ARM_PIVOT_Y, ARM_PIVOT_Z])
23032322
rotate([is_undef(ARM_LIFT_ANGLE) ? 0 : ARM_LIFT_ANGLE, 0, 0])
2304-
translate([0, ARM_TIP_X, ARM_TIP_Z])
2323+
translate([0, ARM_TIP_X + BUCKET_PIVOT_Y_OFFSET, ARM_TIP_Z])
23052324
{
23062325
// Bucket rotates about this pivot
2326+
// BUCKET_PIVOT_Y_OFFSET shifts bucket and lugs together toward/away from arms
23072327
rotate([BUCKET_TILT_ANGLE, 0, 0]) {
23082328
// Pivot Lugs: U-Channel brackets bolted to bucket back plate
23092329
// The Pivot Lug Hole must be at (0,0,0) of this group (which is the Arm Tip/Pivot).
@@ -2415,9 +2435,9 @@ module bucket_cylinders() {
24152435
// Tilt about X at arm tip
24162436
bucket_tilted = rot_x(bucket_local, BUCKET_TILT_ANGLE);
24172437

2418-
// Position relative to arm tip
2438+
// Position relative to arm tip (including BUCKET_PIVOT_Y_OFFSET)
24192439
bucket_at_arm_tip = [bucket_tilted[0],
2420-
ARM_TIP_X + bucket_tilted[1],
2440+
ARM_TIP_X + BUCKET_PIVOT_Y_OFFSET + bucket_tilted[1],
24212441
ARM_TIP_Z + bucket_tilted[2]];
24222442

24232443
// Rotate by arm angle

LifeTrac-v25/mechanical_design/openscad/lifetrac_v25_params.scad

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ BUCKET_FRONT_CLEARANCE = BUCKET_FRONT_CLEARANCE_BASE + BUCKET_FRONT_CLEARANCE_AD
8686
// We align the pivot to be at 1/5 of the bucket height (standard stability position)
8787
BUCKET_PIVOT_HEIGHT_FROM_BOTTOM = BUCKET_HEIGHT / 5; // 450 / 5 = 90mm
8888

89+
// Bucket Pivot Y Offset: Shifts bucket and lugs together toward/away from arms
90+
// Negative values move toward arms (back), positive moves away (forward)
91+
// Used to center the lug pin with the arm tip pin hole
92+
// DEFINED EARLY so arm kinematics can account for it
93+
BUCKET_PIVOT_Y_OFFSET = -2.5 * 25.4; // -63.5mm (~2.5 inches toward arms)
94+
8995
// =============================================================================
9096
// LOADER ARM DIMENSIONS
9197
// =============================================================================
@@ -326,29 +332,44 @@ ARM_MAIN_LEN = _L_main_kinematic - ARM_OVERLAP + _geom_correction;
326332
ARM_DROP_EXT = 80;
327333
PIVOT_HOLE_X_FROM_FRONT = BUCKET_PIVOT_PIN_DIA; // Reverted to 1" (25.4mm) per request (Forward position)
328334

329-
ARM_DROP_LEN = _L_drop_kinematic - ARM_DROP_EXT + PIVOT_HOLE_X_FROM_FRONT;
335+
// Leg shortening adjustment - shortens visual leg WITHOUT changing arm rotation
336+
// This raises the pin hole higher above ground while keeping main arm angle fixed
337+
// Target: Pin hole center at 1/5 bucket height (90mm) from ground level
338+
// The arm hole is at PIVOT_HOLE_Z_FROM_BOTTOM (127mm) from tube bottom
339+
ARM_LEG_SHORTEN = 37 + 25.4 + 6.35 + 25.4 + 6.35; // 100.5mm - added 0.25 inch to previous value
340+
341+
// Visual leg length (what gets rendered)
342+
ARM_DROP_LEN = _L_drop_kinematic - ARM_DROP_EXT + PIVOT_HOLE_X_FROM_FRONT - ARM_LEG_SHORTEN;
343+
344+
// Kinematic leg length (used for tip position calculation - keeps arm angle unchanged)
345+
_ARM_DROP_LEN_KINEMATIC = _L_drop_kinematic - ARM_DROP_EXT + PIVOT_HOLE_X_FROM_FRONT; // Original unshortened
330346

331347
ARM_PIVOT_EXT = 40;
332348
PIVOT_HOLE_EDGE_OFFSET = 1.5 * 25.4;
333-
// PIVOT_HOLE_Z_FROM_BOTTOM set to Top Edge (Tangent to Top)
334-
// This aligns the pivot with the "Upper/Outer" edge of the arm profile.
335-
PIVOT_HOLE_Z_FROM_BOTTOM = TUBE_2X6_1_4[1] - PIVOT_HOLE_X_FROM_FRONT;
349+
// PIVOT_HOLE_Z_FROM_BOTTOM: Original position at top edge of tube
350+
// This keeps the hole position on the arm profile unchanged
351+
PIVOT_HOLE_Z_FROM_BOTTOM = TUBE_2X6_1_4[1] - PIVOT_HOLE_X_FROM_FRONT; // 127mm - original position
336352

337353
echo("DEBUG: Final Parameters:");
338354
echo(" ARM_SHAPE_ANGLE:", ARM_SHAPE_ANGLE);
339355
echo(" ARM_MAIN_LEN:", ARM_MAIN_LEN);
340-
echo(" ARM_DROP_LEN:", ARM_DROP_LEN);
356+
echo(" ARM_DROP_LEN (visual):", ARM_DROP_LEN);
357+
echo(" _ARM_DROP_LEN_KINEMATIC:", _ARM_DROP_LEN_KINEMATIC);
358+
echo(" ARM_LEG_SHORTEN:", ARM_LEG_SHORTEN);
359+
echo(" PIVOT_HOLE_Z_FROM_BOTTOM:", PIVOT_HOLE_Z_FROM_BOTTOM);
341360

342361
// Vector from Main Pivot to Bucket Pivot (For reference)
362+
// Use KINEMATIC leg length to keep arm rotation unchanged
343363
_bend_angle = 180 - ARM_ANGLE; // Note: ARM_ANGLE is now possibly obsolete if we use SHAPE_ANGLE
344-
_drop_vec_len = ARM_DROP_LEN + ARM_DROP_EXT - PIVOT_HOLE_X_FROM_FRONT; // Hole X position (from front edge)
364+
_drop_vec_len = _ARM_DROP_LEN_KINEMATIC + ARM_DROP_EXT - PIVOT_HOLE_X_FROM_FRONT; // Use kinematic length
345365
_tube_h = TUBE_2X6_1_4[1];
346366
_hole_z_offset = PIVOT_HOLE_Z_FROM_BOTTOM; // Hole Z position (from bottom edge)
347367

348368
_dx = _drop_vec_len * cos(_bend_angle) + (_hole_z_offset - _tube_h) * sin(_bend_angle);
349369
_dz = -_drop_vec_len * sin(_bend_angle) + (_hole_z_offset - _tube_h) * cos(_bend_angle);
350370

351371
// Calculate Tip Position (Top/Effective Pivot Point)
372+
// This uses kinematic leg length so arm angle stays the same
352373
ARM_TIP_X = (ARM_MAIN_LEN + ARM_OVERLAP) + _dx; // Removed +50 error
353374
ARM_TIP_Z = _tube_h + _dz;
354375

@@ -363,8 +384,11 @@ echo("ARM_TIP_X =", ARM_TIP_X);
363384
echo("ARM_TIP_Z =", ARM_TIP_Z);
364385

365386
// Calculate angles for kinematics
366-
_x_rel = ARM_TIP_X;
367-
_z_rel = ARM_TIP_Z - _tube_h/2;
387+
// Use ARM_TIP_X and ARM_TIP_Z directly - these represent the bucket pivot position
388+
// relative to the arm pivot in arm-local coordinates (before rotation)
389+
// Include BUCKET_PIVOT_Y_OFFSET to get actual bucket pivot position
390+
_x_rel = ARM_TIP_X + BUCKET_PIVOT_Y_OFFSET;
391+
_z_rel = ARM_TIP_Z; // Fixed: removed _tube_h/2 offset to match bucket_attachment()
368392

369393
_arm_eff_len = sqrt(pow(_x_rel, 2) + pow(_z_rel, 2));
370394
arm_alpha_calc = atan2(-_z_rel, _x_rel); // Angle below horizontal (positive value)
@@ -491,12 +515,20 @@ LIFT_CYL_BASE_Y = max(50, min(WHEEL_BASE/2, _calc_base_y + 10)); // Current logi
491515
// We need to verify the pin-to-base distance.
492516
// For now, we set BUCKET_LUG_OFFSET to this distance.
493517
// Let's assume the lug height (base to pin center) is roughly 50mm (2").
494-
// User Update: Shift bucket backwards closely to align pivot holes.
495-
BUCKET_LUG_OFFSET = 25; // Adjusted (35->25) to align pin with leg hole (Shift backwards)
496-
497-
// Visual adjustment to shift bucket down without affecting kinematic target _T
498-
// Used to calibrate visual ground contact
499-
BUCKET_VISUAL_Z_OFFSET = -10;
518+
// User Update: Shift bucket backwards to align pivot pin with arm leg hole.
519+
// The U-channel lug (3x3 tube) outer back surface is at size/2 from pin center (after 90deg rotation)
520+
// Lug back must be flush with bucket back plate (see DESIGN_RULES.md)
521+
// Bucket back plate back face (Y=0 in bucket local) must align with lug outer back surface
522+
// So BUCKET_LUG_OFFSET = size/2 makes lug outer back flush with bucket plate back face
523+
BUCKET_LUG_OFFSET = TUBE_3X3_1_4[0]/2; // 38.1mm: Lug outer back flush with bucket back plate back face
524+
525+
// Note: BUCKET_PIVOT_Y_OFFSET is defined earlier in this file (after BUCKET_PIVOT_HEIGHT_FROM_BOTTOM)
526+
// to ensure arm kinematics calculations can account for it
527+
528+
// Visual adjustment to shift bucket without affecting kinematic target _T
529+
// At BUCKET_VISUAL_Z_OFFSET = 0, bucket bottom should be exactly at ground (Z=0) when flat
530+
// Calculation: pivot_z(90) - (BUCKET_HEIGHT(450) - BUCKET_PIVOT_HEIGHT_FROM_BOTTOM(90)) = 0
531+
BUCKET_VISUAL_Z_OFFSET = 0; // Bucket bottom flat on ground
500532
BUCKET_BODY_Z_OFFSET = 0; // Keep bucket body aligned to pivot; use BUCKET_GROUND_CLEARANCE to set ground contact
501533

502534
// Bucket Cylinder Mount Parameters

0 commit comments

Comments
 (0)