Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bayonet Mount #1323

Open
harrislapiroff opened this issue Dec 7, 2023 · 15 comments
Open

Bayonet Mount #1323

harrislapiroff opened this issue Dec 7, 2023 · 15 comments
Assignees
Labels
Defer Deferred until after the next major release. Enhancement New feature or request

Comments

@harrislapiroff
Copy link

Is your feature request related to a problem? Please describe.
I often want a twist-and-lock feature on my models and haven't found a quick way to achieve that with existing components in this library.

Describe the solution you'd like
A bayonet mount option similar to the threading options. Some examples of connections:

image
source

image
source

Describe alternatives you've considered
I might have to build my own, but I'm not great at building reusable components, so I'm not sure if I'll be confident in contributing it back upstream.

@adrianVmariano
Copy link
Collaborator

This looks awkward to print, with support needed for both parts of the structure.

@revarbat
Copy link
Collaborator

I have some ideas on how to make a couple twist-lock style mounts that would not require support, but I'll need to flesh the idea out.

@adrianVmariano
Copy link
Collaborator

I looked at the linked model. I didn't download its STL...but it looks like their concept is quite different from the picture shown above. It is almost like a fractional screw thread in operation. That is, you have a flat tab which could be printed down on the built plate. The other side could be more trouble, depending on how it's done.

It seems like we really should focus on the major blockers right now and defer things like this to after the release.

@harrislapiroff
Copy link
Author

@adrianVmariano Yes, maybe including the wikipedia image was more confusing than not. The design on the moon lamp printed fine on my printer without supports—the top bit is bridged

@harrislapiroff
Copy link
Author

close up image
image

@revarbat
Copy link
Collaborator

Agreed, though, that this should defer to 2.1.

@revarbat revarbat added Enhancement New feature or request Defer Deferred until after the next major release. labels Dec 18, 2023
@harrislapiroff
Copy link
Author

As a proof of concept I coded up this twist lock mechanism that printed on my printer with no supports. I don't think my code is up to snuff for contributing myself, but maybe this can provide some inspiration or a starting point. (I'd be happy to try to get it to a better place, but I might need a fair bit of guidance 😅)

include <BOSL2/std.scad>

module thread_profile (
    width = 2,
    height = 1,
    bevel_top = 1.5,
    bevel_bottom = 1.5,
) {
    polygon(points = [
        [0, 0],
        [width, bevel_bottom],
        [width, bevel_bottom + height],
        [0, bevel_bottom + height + bevel_top],
    ]);
}

module twist_lock_thread (
    d = 10,
    pins = 4,
    pin_extrude_width = 2,
    pin_arc_angle = 30,
    pin_height = 0.5,
    pin_bevel_height_top = 0.75,
    pin_bevel_height_bottom = 0.75,
    anchor, spin, orient
) {
    between_angle = 360 / pins - pin_arc_angle;
    total_h = pin_height + pin_bevel_height_bottom + pin_bevel_height_top;
    total_d = d + pin_extrude_width * 2;

    attachable(
        anchor, spin, orient,
        d = total_d,
        h = total_h
    ) {
        for (i = [0 : pins - 1]) {
            zrot(i * between_angle + i * pin_arc_angle)
            down(total_h / 2) // center vertically
            rotate_extrude(angle=pin_arc_angle)
            right(d / 2)
            thread_profile(
                width = pin_extrude_width,
                height = pin_height,
                bevel_top = pin_bevel_height_top,
                bevel_bottom = pin_bevel_height_bottom
            );
        };

        children();
    }
};

module twist_lock_rod_insert (
    d = 10,
    h = 10,
    rod_chamfer_top = 0,
    rod_chamfer_bottom = 0,
    pins = 2,
    pin_extrude_width = 1.5,
    pin_arc_angle = 60,
    pin_height = 0.5,
    pin_bevel_height_top = 1.5,
    pin_bevel_height_bottom = 0,
    pin_from_bottom = 0,
    eps = 0.01,
    anchor, spin, orient
) {
    attachable(
        anchor, spin, orient,
        d = d + pin_extrude_width * 2,
        h = h
    ) {
        cyl(
            d = d,
            h = h,
            chamfer1 = rod_chamfer_bottom,
            chamfer2 = rod_chamfer_top,
        )
        position(BOTTOM)
        up(pin_from_bottom)
        twist_lock_thread(
            d = d - eps * 2,
            pins = pins,
            pin_extrude_width = pin_extrude_width + eps * 2,
            pin_arc_angle = pin_arc_angle,
            pin_height = pin_height,
            pin_bevel_height_top = pin_bevel_height_top,
            pin_bevel_height_bottom = pin_bevel_height_bottom,
            anchor = BOTTOM
        );
        
        children();
    }
}

// Mask for the hole a twist lock rod goes into
module twist_lock_rod_mask (
    d = 10,
    h = 10,
    rod_chamfer_bottom = 0,
    rod_chamfer_top = 0,
    pins = 2,
    pin_extrude_width = 1,
    pin_arc_angle = 60,
    pin_height = 0.5,
    pin_bevel_height_top = 1.5,
    pin_bevel_height_bottom = 0,
    pin_from_bottom = 0,
    eps = 0.01,
    anchor, spin, orient
) {
    slop = get_slop();
    between_angle = 360 / pins - pin_arc_angle;
    outer_circumference = (d + pin_extrude_width * 2);
    angle_slop = outer_circumference * slop / 360;
    angle_eps = outer_circumference * eps / 360;

    d_ = d + slop * 2;
    h_ = h;
    pin_height_ = pin_height + slop * 2;
    pin_from_bottom_ = pin_from_bottom > slop / 2 ? pin_from_bottom - slop / 2 : 0;

    attachable(
        anchor, spin, orient,
        d = max(d + pin_extrude_width * 2 + slop, d + rod_chamfer_top * 2 + slop),
        h = h
    ) {
        union() {
            twist_lock_rod_insert(
                d = d_,
                h = h_,
                rod_chamfer_bottom = -rod_chamfer_bottom,
                rod_chamfer_top = -rod_chamfer_top,
                pins = pins,
                pin_extrude_width = pin_extrude_width,
                pin_arc_angle = pin_arc_angle,
                pin_height = pin_height_,
                pin_bevel_height_top = pin_bevel_height_top,
                pin_bevel_height_bottom = pin_bevel_height_bottom,
                pin_from_bottom = pin_from_bottom_,
            )
            position(BOTTOM)
            // Channels
            for (i = [0 : pins - 1]) {
                zrot(i * between_angle + (i + 1) * pin_arc_angle - angle_eps)
                up(pin_from_bottom)
                pie_slice(
                    h = h_ - pin_from_bottom_,
                    d = d_ + pin_extrude_width * 2,
                    ang = pin_arc_angle + angle_slop * 2,
                );
            }
        }
        
        children();
    }
}

Here's a sample block I printed using it:

image

image

image

@adrianVmariano
Copy link
Collaborator

I favor the strategy that you get your version up to snuff with guidance. I took a quick look at where things are at the moment.

I think it might be better to make the "rod" portion create only the two flanges as an attachable object that one can attach to a suitable cylinder. That eliminates all the rod parameters. You need to construct it so that the faceting aligns with a cylinder of the same facet count.

image

See how faceting is misaligned? Private functions/modules should start with underscore.

Think about your API and whether you've got the most rational, sensible API and the best names. Then document it following the doc texts in the BOSL2 source as a guide so we know how it's supposed to work. (You have quite a few parameters and it's not at all clear what they should do.)

The use of eps seems inconsistent (usually it's a very small value defaulting to EPSILON=1e-9).

How does the user control amount of twist required to lock? That's a natural parameter that's not obvious. Actually, now that I think about it....how/why does it lock? It looks like there is no tapering or anything that would make it lock.

@harrislapiroff
Copy link
Author

harrislapiroff commented Feb 10, 2024

@adrianVmariano I guess technically here it doesnt "lock" in place around the z axis—it's just that twisting it in locks it vertically. I'd like to design some sort of snapping mechanism, but haven't worked it out yet. Short of figuring that out, you're right that maybe a taper would allow it to be friction tightened.

I kinda wanted to keep the ability to add multiple flanges—my dream is for it to be as flexible as the threading module. But maybe starting with a single design and working out is smarter?

I'm mostly concerned about making the use of attachables consistent with what's in the BOSL2 codebase, but it seems like I have some more fundamental work to do first 😅 Thanks for the tips—will work on those!

@adrianVmariano
Copy link
Collaborator

If it snap locked in place....how would it unlock? A taper would definitely allow it to tighten with friction. I think that there is something to be said for thinking out what you want ahead of time because a new tweak might require a redesign of core stuff you already wrote. In particular, I think adding a taper may be difficult with rotate extrude. (Most of the core stuff in BOSL2, like screw threads, is done with direct creation of a polyhedron, because that's just more flexible and faster.)

But with regards to generality, you need to balance that with not letting the project run away from you and not having to print 75 test models for all the different designs. So you might just sit down and make a list of all the desirable characteristics of this type of mechanism and then define a scope for your initial implementation.

Getting the anchoring right will not be a major issue, and we can definitely help with that.

@Jasonkoolman
Copy link

Jasonkoolman commented Dec 27, 2024

@harrislapiroff did you make any progress on your twist lock mechanism? Looks like a solid implementation already. Another take on the Bayonet Lock with OpenSCAD: https://www.thingiverse.com/thing:6536797. It locks on the Z-axis.

I'm trying to recreate the twist lock mechanism of a Bambu spool:

image
image

The tapering part will be challenging. I can't find ways to taper ends using BOSL2. Probably need to construct a polyhedron. I have some leads to follow like this thread and this solution by @adrianVmariano . I also noticed that spiral sweep accepts lead in/out arguments. I'll start digging.

@adrianVmariano
Copy link
Collaborator

The problem with the referenced method is that the taper happens in one straight step. Not sure if that's good enough for your application. You might need to do something like how spiral sweep works, where it adds slices that are adjusted for the taper, but I think the code as written only makes centered tapers.

@Jasonkoolman
Copy link

Gotcha - thanks for the tips. I might opt for the lazy route by using edge masks, or leave out the tapering as it is not an essential part of the locking mechanism.

Just as in harris's solution, I'm having issues where faces are misaligned when I use rotate sweep or extrude at angles other than a multiple of 90:
image

You mentioned "You need to construct it so that the faceting aligns with a cylinder of the same facet count.". How would one go about this? Would I maybe need to subdivide the sweep path to add vertices at certain points (angle steps)? I did not manage to find any straightforward example.

@adrianVmariano
Copy link
Collaborator

I don't have quite enough information to give a solid answer. The segs() function can return the number of segments based on the radius and the inherited $fn and $fa and $fs values so the general process would be to determine the number of factets of the cylinder you want to mate to using segs() and then use the same number of facets for the part you are adding. But there is a messy last segment, potentially. To make that work in all cases you'd need something that gives you more control than rotate sweep, because it can't make a partial segment. I think that might require path_sweep, or spiral sweep I think should get this right.

@adrianVmariano
Copy link
Collaborator

Another strategy would be to round the angle to the nearest whole segment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Defer Deferred until after the next major release. Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants