Exit Full View
Up

/Bike/PannierClip.foocad

PannierClip

The clip on my Aqua 14 pannier broke (on the first ride!)

This is a simplified replacement without the small springy part in the middle, which seems irrelevant to me (it clips on firmly without it).

There is an obvious weak point where the screw attaches (especially in the original). The latest version is thicker than the origianl to try to compensate.

I copied the curve by tracing a photo, and I think it is pretty close to the original.

Print Notes

Use a generous brim (the model is very small where it touches the bed). I used 4 perimeters and 30% infill. Maybe bump up both, given that the design as a weak point!

PLA is fine, but maybe PETG would be better (stronger and springier).

New (fatter) version : White PLA 5 perimeters 30% infill Black PLA : 8 perimeters 30% infill

Versions

16/2/2023 Made it fatter than the original, as I've had 2 failures of the old design.
FooCAD Source Code
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*

class PannierClip : Model {
    
    var thickness = 24

    override fun build() : Shape3d {
    
        // want the "rect" lined up with the Y axis, to make it easy
        // to make the hole through it.
        val angle = 13.5

        val doc = SVGParser().parseFile( "pannierClip.svg" )
        val fiveP = doc.shapes["fivecm"] // A 5cm rectangle. Used to scale to the correct size.
        val scale = 50.0 / fiveP.size.x

        val mainP1 = doc.shapes["main"].scale(scale).rotate(angle)
        val rectP = doc.shapes["rect"].scale(scale).rotate(angle).toPolygon()
        // Force the tab to be perfectly lined up, even if angle is a little off.
        val tabP = rectP.boundingSquare()
            .scaleX( 6.5 / rectP.size.x )
            .centerTo(rectP.middle)
            .scaleY( 0.9 ).frontTo(rectP.front) // Grr, was too long!


        val main = mainP1.chamferedExtrude( thickness, 1 )
        val rect = tabP.roundAllCorners(1).chamferedExtrude( thickness, 1.5 )

        val hole = Cylinder.hole( 100, 2.5, 8 )
            .rotateX(90)
            .centerXTo( rectP.middle.x )
            .frontTo( rectP.front )
            .centerZTo( thickness/2 )
        val hole2 = Cylinder.hole( 10, 5, 8 )
            .rotateX(90)
            .centerXTo( rectP.middle.x )
            .backTo( rectP.front-1.2 +3.5 )
            .centerZTo( thickness/2 )

        val all = (main + rect - hole - hole2).centerXY()

        val ear = Cylinder(0.3, 6).color("green")
        val ears = ear.rightTo(all.left+2).backTo(0) +
            ear.translate( 10,-7, 0) +
            ear.translate( 26, 12, 0 )
        return all // + ears
    }

}