Completing Joints docs

This commit is contained in:
gumyr 2023-08-16 20:53:29 -04:00
parent 03197a9b73
commit bdaf863e71
7 changed files with 164 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
docs/assets/joint-latch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
docs/assets/joint-slide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/assets/rod_end.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View file

@ -76,27 +76,72 @@ one at the face end - both of which are shown in the above image (generated by o
Revolute Joint Revolute Joint
************** **************
Component rotates around axis like a hinge. Component rotates around axis like a hinge. The :ref:`joint_tutorial` covers Revolute Joints in detail.
During instantiation of a :class:`~topology.RevoluteJoint` there are three parameters not present with
Rigid Joints: ``axis``, ``angle_reference``, and ``range`` that allow the circular motion to be fully
defined.
When :meth:`~topology.Joint.connect_to` with a Revolute Joint, an extra ``angle`` parameter is present
which allows one to change the relative position of joined parts by changing a single value.
************ ************
Linear Joint Linear Joint
************ ************
Component moves along a single axis. Component moves along a single axis as with a sliding latch shown here:
.. image:: assets/joint-latch-slide.png
The code to generate these components follows:
.. literalinclude:: slide_latch.py
:emphasize-lines: 30, 52, 55
.. image:: assets/joint-latch.png
:width: 65 %
.. image:: assets/joint-slide.png
:width: 27.5 %
Note how the slide is constructed in a different orientation than the direction of motion. The
three highlighted lines of code show how the joints are created and connected together:
* The :class:`~topology.LinearJoint` has an axis and limits of movement
* The :class:`~topology.RigidJoint` has a single location, orientated such that the knob will ultimately be "up"
* The ``connect_to`` specifies a position that must be within the predefined limits.
The slider can be moved back and forth by just changing the ``position`` value. Values outside
of the limits will raise an exception.
***************** *****************
Cylindrical Joint Cylindrical Joint
***************** *****************
Component rotates around and moves along a single axis like a screw. A :class:`~topology.CylindricalJoint` allows a component to rotate around and moves along a single axis
like a screw combining the functionality of a :class:`~topology.LinearJoint` and a
:class:`~topology.RevoluteJoint` joint. The ``connect_to`` for these joints have both ``position`` and
``angle`` parameters as shown below extracted from the joint tutorial.
.. code-block::python
hinge_outer.joints["hole2"].connect_to(m6_joint, position=5 * MM, angle=30)
********** **********
Ball Joint Ball Joint
********** **********
A component rotates around all 3 axes using a gimbal system (3 nested rotations). A component rotates around all 3 axes using a gimbal system (3 nested rotations). A :class:`~topology.BallJoint`
is found within a rod end as shown here:
********** .. image:: assets/rod_end.png
Conclusion
********** .. literalinclude:: rod_end.py
:emphasize-lines: 37-42,49,51
Note how limits are defined during the instantiation of the ball joint when ensures that the pin or bolt
within the rod end does not interfer with the rod end itself. The ``connect_to`` sets the three angles
(only two are significant in this example).

53
docs/rod_end.py Normal file
View file

@ -0,0 +1,53 @@
from build123d import *
from bd_warehouse.thread import IsoThread
from ocp_vscode import *
# Create the thread so the min radius is available below
thread = IsoThread(
major_diameter=8, pitch=1.25, length=20, end_finishes=("fade", "raw")
)
with BuildPart() as rod_end:
# Create the outer shape
with BuildSketch():
Circle(22.25 / 2)
with Locations((0, -12)):
Rectangle(8, 1)
make_hull()
split(bisect_by=Plane.YZ)
revolve(axis=Axis.Y)
# Refine the shape
with BuildSketch(Plane.YZ) as s2:
Rectangle(25, 8, align=(Align.MIN, Align.CENTER))
Rectangle(9, 10, align=(Align.MIN, Align.CENTER))
chamfer(s2.vertices(), 0.5)
revolve(axis=Axis.Z, mode=Mode.INTERSECT)
# Add the screw shaft
Cylinder(
thread.min_radius,
30,
rotation=(90, 0, 0),
align=(Align.CENTER, Align.CENTER, Align.MIN),
)
# Cutout the ball socket
Sphere(15.89 / 2, mode=Mode.SUBTRACT) # Add thread
with Locations((0, -30, 0)):
add(thread, rotation=(-90, 0, 0))
# Create the ball joint
BallJoint(
"socket",
rod_end.part,
joint_location=Location(),
angular_range=((-14, 14), (-14, 14), (0, 360)),
)
with BuildPart() as ball:
Sphere(15.88 / 2)
Box(50, 50, 13, mode=Mode.INTERSECT)
Hole(4)
ball.part.color = Color("aliceblue")
RigidJoint("ball", ball.part, joint_location=Location())
rod_end.part.joints["socket"].connect_to(ball.part.joints["ball"], angles=(5, 10, 0))
show(rod_end.part, ball.part)

59
docs/slide_latch.py Normal file
View file

@ -0,0 +1,59 @@
from build123d import *
from ocp_vscode import *
with BuildPart() as latch:
# Basic box shape to start with filleted corners
Box(70, 30, 14)
end = latch.faces().sort_by(Axis.X)[-1] # save the end with the hole
fillet(latch.edges().filter_by(Axis.Z), 2)
fillet(latch.edges().sort_by(Axis.Z)[-1], 1)
# Make screw tabs
with BuildSketch(latch.faces().sort_by(Axis.Z)[0]) as l4:
with Locations((-30, 0), (30, 0)):
SlotOverall(50, 10, rotation=90)
Rectangle(50, 30)
fillet(l4.vertices(Select.LAST), radius=2)
extrude(amount=-2)
with GridLocations(60, 40, 2, 2):
Hole(2)
# Create the hole from the end saved previously
with BuildSketch(end) as slide_hole:
add(end)
offset(amount=-2)
fillet(slide_hole.vertices(), 1)
extrude(amount=-68, mode=Mode.SUBTRACT)
# Slot for the hangle to slide in
with BuildSketch(latch.faces().sort_by(Axis.Z)[-1]):
SlotOverall(32, 8)
extrude(amount=-2, mode=Mode.SUBTRACT)
# The slider will move align the x axis 12mm in each direction
LinearJoint("latch", latch.part, axis=Axis.X, linear_range=(-12, 12))
with BuildPart() as slide:
# The slide will be a little smaller than the hole
with BuildSketch() as s1:
add(slide_hole.sketch)
offset(amount=-0.25)
# The extrusions aren't symmetric
extrude(amount=46)
extrude(slide.faces().sort_by(Axis.Z)[0], amount=20)
# Round off the ends
fillet(slide.edges().group_by(Axis.Z)[0], 1)
fillet(slide.edges().group_by(Axis.Z)[-1], 1)
# Create the knob
with BuildSketch() as s2:
with Locations((12, 0)):
SlotOverall(15, 4, rotation=90)
Rectangle(12, 7, align=(Align.MIN, Align.CENTER))
fillet(s2.vertices(Select.LAST), 1)
split(bisect_by=Plane.XZ)
revolve(axis=Axis.X)
# Align the joint to Plane.ZY flipped
RigidJoint("slide", slide.part, Location(-Plane.ZY))
# Position the slide in the latch: -12 >= position <= 12
latch.part.joints["latch"].connect_to(slide.part.joints["slide"], position=12)
# show(latch.part, render_joints=True)
# show(slide.part, render_joints=True)
show(latch.part, slide.part, render_joints=True)