summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Shreve <j.a.shreve@gmail.com>2021-09-02 20:51:42 -0400
committerJoshua Shreve <j.a.shreve@gmail.com>2021-09-02 20:51:42 -0400
commit3ebbe5dd2cbc406e93418ac9fb06fbbf175785ba (patch)
tree9ceed478a0334096f2d368e601adb341f20266a4 /src
parent27f491bda62c18e314380ddc6456962a2417b84b (diff)
Added PCB controller mount feature options.
Also, working on modular trackball, though ball bearings make it difficult to decouple as they typically land in the middle of the walls and webs.
Diffstat (limited to 'src')
-rw-r--r--src/dactyl_manuform.py177
-rw-r--r--src/generate_configuration.py44
-rw-r--r--src/helpers_blender.py3
-rw-r--r--src/helpers_cadquery.py31
-rw-r--r--src/helpers_solid.py31
-rw-r--r--src/run_config.json50
6 files changed, 277 insertions, 59 deletions
diff --git a/src/dactyl_manuform.py b/src/dactyl_manuform.py
index a04a291..9913086 100644
--- a/src/dactyl_manuform.py
+++ b/src/dactyl_manuform.py
@@ -4,6 +4,7 @@ import os.path as path
import getopt, sys
import json
import os
+import copy
from scipy.spatial import ConvexHull as sphull
@@ -273,30 +274,37 @@ def single_plate(cylinder_segments=100, side="right"):
return plate
def trackball_cutout(segments=100, side="right"):
- shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height)
+ if trackball_modular:
+ hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance+trackball_modular_lip_width)-.1
+ shape = cylinder(hole_diameter / 2, trackball_hole_height)
+ else:
+ shape = cylinder(trackball_hole_diameter / 2, trackball_hole_height)
return shape
def trackball_socket(segments=100, side="right"):
- # shape = sphere(ball_diameter / 2)
- # cyl = cylinder(ball_diameter / 2 + 4, 20)
- # cyl = translate(cyl, (0, 0, -8))
- # shape = union([shape, cyl])
+ if trackball_modular:
+ hole_diameter = ball_diameter + 2 * (ball_gap + ball_wall_thickness + trackball_modular_clearance)
+ ring_diameter = hole_diameter + 2 * trackball_modular_lip_width
+ ring_height = trackball_modular_ring_height
+ ring_z_offset = mount_thickness - trackball_modular_ball_height
+ shape = cylinder(ring_diameter / 2, ring_height)
+ shape = translate(shape, (0, 0, -ring_height / 2 + ring_z_offset))
- tb_file = path.join(parts_path, r"trackball_socket_body_34mm")
- tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm")
- sens_file = path.join(parts_path, r"trackball_sensor_mount")
- senscut_file = path.join(parts_path, r"trackball_sensor_cutter")
+ cutter = cylinder(hole_diameter / 2, ring_height + .2)
+ cutter = translate(cutter, (0, 0, -ring_height / 2 + ring_z_offset))
+ sensor = None
- # shape = import_file(tb_file)
- # # shape = difference(shape, [import_file(senscut_file)])
- # # shape = union([shape, import_file(sens_file)])
- # cutter = import_file(tbcut_file)
+ else:
+ tb_file = path.join(parts_path, r"trackball_socket_body_34mm")
+ tbcut_file = path.join(parts_path, r"trackball_socket_cutter_34mm")
+ sens_file = path.join(parts_path, r"trackball_sensor_mount")
+ senscut_file = path.join(parts_path, r"trackball_sensor_cutter")
- shape = import_file(tb_file)
- sensor = import_file(sens_file)
- cutter = import_file(tbcut_file)
- cutter = union([cutter, import_file(senscut_file)])
+ shape = import_file(tb_file)
+ sensor = import_file(sens_file)
+ cutter = import_file(tbcut_file)
+ cutter = union([cutter, import_file(senscut_file)])
# return shape, cutter
return shape, cutter, sensor
@@ -3233,8 +3241,130 @@ def external_mount_hole():
)
return shape
-def generate_trackball(pos, rot):
+
+pcb_mount_ref_position = key_position(
+ #TRRS POSITION IS REFERENCE BY CONVENIENCE
+ list(np.array(wall_locate3(0, 1)) + np.array([0, (mount_height / 2), 0])), 0, 0
+)
+
+pcb_mount_ref_position[0] = pcb_mount_ref_position[0] + pcb_mount_ref_offset[0]
+pcb_mount_ref_position[1] = pcb_mount_ref_position[1] + pcb_mount_ref_offset[1]
+pcb_mount_ref_position[2] = 0.0 + pcb_mount_ref_offset[2]
+
+def pcb_usb_hole():
+ debugprint('pcb_holder()')
+ pcb_usb_position = copy.deepcopy(pcb_mount_ref_position)
+ pcb_usb_position[0] = pcb_usb_position[0] + pcb_usb_hole_offset[0]
+ pcb_usb_position[1] = pcb_usb_position[1] + pcb_usb_hole_offset[1]
+ pcb_usb_position[2] = pcb_usb_position[2] + pcb_usb_hole_offset[2]
+
+ shape = box(*pcb_usb_hole_size)
+ shape = translate(shape,
+ (
+ pcb_usb_position[0],
+ pcb_usb_position[1],
+ pcb_usb_hole_size[2] / 2 + pcb_usb_hole_z_offset + usb_holder_thickness,
+ )
+ )
+ return shape
+
+
+
+pcb_holder_position = copy.deepcopy(pcb_mount_ref_position)
+pcb_holder_position[0] = pcb_holder_position[0] + pcb_holder_offset[0]
+pcb_holder_position[1] = pcb_holder_position[1] + pcb_holder_offset[1]
+pcb_holder_position[2] = pcb_holder_position[2] + pcb_holder_offset[2]
+pcb_holder_thickness = pcb_holder_size[2]
+
+def pcb_holder():
+ debugprint('pcb_holder()')
+ shape = box(*pcb_holder_size)
+ shape = translate(shape,
+ (
+ pcb_holder_position[0],
+ pcb_holder_position[1] - pcb_holder_size[1] / 2,
+ pcb_holder_thickness / 2,
+ )
+ )
+ return shape
+
+
+def wall_thinner():
+ debugprint('wall_thinner()')
+ shape = box(*wall_thinner_size)
+ shape = translate(shape,
+ (
+ pcb_holder_position[0],
+ pcb_holder_position[1] - wall_thinner_size[1]/2,
+ wall_thinner_size[2]/2 + pcb_holder_thickness,
+ )
+ )
+ return shape
+
+
+
+
+def trrs_hole():
+ debugprint('trrs_hole()')
+ trrs_position = copy.deepcopy(pcb_mount_ref_position)
+ trrs_position[0] = trrs_position[0] + trrs_offset[0]
+ trrs_position[1] = trrs_position[1] + trrs_offset[1]
+ trrs_position[2] = trrs_position[2] + trrs_offset[2]
+
+ trrs_hole_size = [3, 20]
+
+
+ shape = cylinder(*trrs_hole_size)
+ shape = rotate(shape, [0, 90, 90])
+ shape = translate(shape,
+ (
+ trrs_position[0],
+ trrs_position[1],
+ trrs_hole_size[0] + pcb_holder_thickness,
+ )
+ )
+ return shape
+
+pcb_screw_position = copy.deepcopy(pcb_mount_ref_position)
+pcb_screw_position[1] = pcb_screw_position[1] + pcb_screw_y_offset
+
+def pcb_screw_hole():
+ debugprint('pcb_screw_hole()')
+ holes = []
+ hole = cylinder(*pcb_screw_hole_size)
+ hole = translate(hole, pcb_screw_position)
+ hole = translate(hole, (0, 0, pcb_screw_hole_size[1]/2-.1))
+ holes.append(translate(hole, (pcb_screw_x_offsets[0], 0, 0)))
+ holes.append(translate(hole, (pcb_screw_x_offsets[1], 0, 0)))
+ holes.append(translate(hole, (pcb_screw_x_offsets[2], 0, 0)))
+
+ return holes
+
+
+if oled_center_row is not None:
+ base_pt1 = key_position(
+ list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row-1
+ )
+ base_pt2 = key_position(
+ list(np.array([-mount_width/2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row+1
+ )
+ base_pt0 = key_position(
+ list(np.array([-mount_width / 2, 0, 0]) + np.array([0, (mount_height / 2), 0])), 0, oled_center_row
+ )
+
+ oled_mount_location_xyz = (np.array(base_pt1)+np.array(base_pt2))/2. + np.array(((-left_wall_x_offset/2), 0, 0)) + np.array(oled_translation_offset)
+ oled_mount_location_xyz[2] = (oled_mount_location_xyz[2] + base_pt0[2])/2
+
+ angle_x = np.arctan2(base_pt1[2] - base_pt2[2], base_pt1[1] - base_pt2[1])
+ angle_z = np.arctan2(base_pt1[0] - base_pt2[0], base_pt1[1] - base_pt2[1])
+
+ oled_mount_rotation_xyz = (rad2deg(angle_x), 0, -rad2deg(angle_z)) + np.array(oled_rotation_offset)
+
+
+
+
+def generate_trackball(pos, rot):
precut = trackball_cutout()
precut = rotate(precut, tb_socket_rotation_offset)
precut = translate(precut, tb_socket_translation_offset)
@@ -3883,7 +4013,14 @@ def model_side(side="right"):
if controller_mount_type in ['EXTERNAL']:
s2 = difference(s2, [external_mount_hole()])
- if controller_mount_type in ['None']:
+ if controller_mount_type in ['PCB_MOUNT']:
+ s2 = difference(s2, [pcb_usb_hole()])
+ s2 = difference(s2, [trrs_hole()])
+ s2 = union([s2, pcb_holder()])
+ s2 = difference(s2, [wall_thinner()])
+ s2 = difference(s2, pcb_screw_hole())
+
+ if controller_mount_type in [None, 'None']:
0 # do nothing, only here to expressly state inaction.
s2 = difference(s2, [union(screw_insert_holes(side=side))])
@@ -3922,7 +4059,7 @@ def model_side(side="right"):
if show_caps:
shape = add([shape, ball])
- if (trackball_in_wall or ('TRACKBALL' in thumb_style)) and (side == ball_side or ball_side == 'both'):
+ if ('TRACKBALL' in thumb_style) and (side == ball_side or ball_side == 'both'):
tbprecut, tb, tbcutout, sensor, ball = generate_trackball_in_cluster()
shape = difference(shape, [tbprecut])
diff --git a/src/generate_configuration.py b/src/generate_configuration.py
index f5fa716..1fb89bf 100644
--- a/src/generate_configuration.py
+++ b/src/generate_configuration.py
@@ -21,7 +21,7 @@ shape_config = {
'save_dir': '.',
'config_name': "DM",
- 'show_caps': True,
+ 'show_caps': False,
'show_pcbs': False, #only runs if caps are shown, easist place to initially inject geometry
'nrows': 5, #5, # key rows
@@ -44,11 +44,16 @@ shape_config = {
11 # controls overall height# original=9 with centercol=3# use 16 for centercol=2
),
+ 'web_thickness': 4.0,
+ 'post_size': 0.1,
+ # post_adj': post_size / 2
+ 'post_adj': 0,
+
##############################
# THUMB PARAMETERS
##############################
# 'DEFAULT' 6-key, 'MINI' 5-key, 'CARBONFET' 6-key, 'MINIDOX' 3-key, 'TRACKBALL_ORBYL', 'TRACKBALL_CJ'
- 'thumb_style': 'TRACKBALL_ORBYL',
+ 'thumb_style': 'CARBONFET',
'default_1U_cluster': True, # only used with default, makes top right thumb cluster key 1U
# Thumb key size. May need slight oversizing, check w/ caps. Additional spacing will be automatically added for larger keys.
'minidox_Usize': 1.6,
@@ -109,9 +114,11 @@ shape_config = {
###################################
## Trackball General ##
###################################
- # EXPERIMENTAL
- 'trackball_modular': False, # May add removable trackball in subsequent releases, no current use.
- # END EXPERIMENTAL
+ 'trackball_modular': False, # Added, creates a hole with space for the lip size listed below.
+ 'trackball_modular_lip_width': 3.0, # width of lip cleared out in ring location
+ 'trackball_modular_ball_height': 3.0, # height of ball from ring , used to create identical position to fixed.
+ 'trackball_modular_ring_height': 10.0, # height mount ring down from ball height. Covers gaps on elevated ball.
+ 'trackball_modular_clearance': 0.5, # height of ball from ring, used to create identical position to fixed.
'trackball_Usize': 1.5, # size for inner key near trackball
'ball_side': 'right', #'left', 'right', or 'both'
@@ -294,10 +301,7 @@ shape_config = {
'oled_clip_z_gap': .2,
}
},
- 'web_thickness': 4.0,
- 'post_size': 0.1,
- # post_adj': post_size / 2
- 'post_adj': 0,
+
'screws_offset': 'INSIDE', #'OUTSIDE', 'INSIDE', 'ORIGINAL'
'screw_insert_height': 3.8,
@@ -322,7 +326,7 @@ shape_config = {
# 'USB_TEENSY' = Teensy holder, no RJ9
# 'EXTERNAL' = square cutout for a holder such as the one from lolligagger.
# 'NONE' = No openings in the back.
- 'controller_mount_type': 'EXTERNAL',
+ 'controller_mount_type': 'PCB_MOUNT',
'external_holder_height': 12.5,
'external_holder_width': 28.75,
@@ -332,6 +336,26 @@ shape_config = {
# Offset is from the top inner corner of the top inner key.
###################################
+ ## PCB Screw Mount ##
+ ###################################
+ "pcb_mount_ref_offset": [0, -5, 0],
+ "pcb_holder_size": [34.6, 7, 4],
+ "pcb_holder_offset": [8.9, 0, 0],
+
+ "pcb_usb_hole_size": [7.5, 10.0, 4],
+ "pcb_usb_hole_offset": [15, 0, 4.5],
+
+ "wall_thinner_size": [34, 7, 10],
+
+ "trrs_hole_size": [3, 20],
+ "trrs_offset": [0, 0, 1.5],
+
+ "pcb_screw_hole_size": [.5, 10],
+ "pcb_screw_x_offsets": [- 5.5, 7.75, 22], # for the screw positions off of reference
+ "pcb_screw_y_offset": -2,
+
+
+ ###################################
## Bottom Plate Dimensions
###################################
# COMMON DIMENSION
diff --git a/src/helpers_blender.py b/src/helpers_blender.py
index 9213488..00da8e5 100644
--- a/src/helpers_blender.py
+++ b/src/helpers_blender.py
@@ -82,7 +82,8 @@ def add(shapes):
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape -= item
+ if item is not None:
+ shape -= item
return shape
diff --git a/src/helpers_cadquery.py b/src/helpers_cadquery.py
index 5dc78d1..58a876a 100644
--- a/src/helpers_cadquery.py
+++ b/src/helpers_cadquery.py
@@ -30,6 +30,8 @@ def cone(r1, r2, height):
def rotate(shape, angle):
+ if shape is None:
+ return None
origin = (0, 0, 0)
shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(1, 0, 0), angleDegrees=angle[0])
shape = shape.rotate(axisStartPoint=origin, axisEndPoint=(0, 1, 0), angleDegrees=angle[1])
@@ -38,6 +40,8 @@ def rotate(shape, angle):
def translate(shape, vector):
+ if shape is None:
+ return None
return shape.translate(tuple(vector))
@@ -50,10 +54,11 @@ def union(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape = shape.union(item)
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape = shape.union(item)
return shape
@@ -61,23 +66,27 @@ def add(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape = shape.add(item)
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape = shape.add(item)
return shape
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape = shape.cut(item)
+ if item is not None:
+ shape = shape.cut(item)
return shape
def intersect(shape1, shape2):
- return shape1.intersect(shape2)
-
+ if shape2 is not None:
+ return shape1.intersect(shape2)
+ else:
+ return shape1
def face_from_points(points):
# debugprint('face_from_points()')
diff --git a/src/helpers_solid.py b/src/helpers_solid.py
index 174d65a..2557e01 100644
--- a/src/helpers_solid.py
+++ b/src/helpers_solid.py
@@ -23,10 +23,14 @@ def cone(r1, r2, height):
def rotate(shape, angle):
+ if shape is None:
+ return None
return sl.rotate(angle)(shape)
def translate(shape, vector):
+ if shape is None:
+ return None
return sl.translate(tuple(vector))(shape)
@@ -47,10 +51,11 @@ def union(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
return shape
@@ -58,23 +63,27 @@ def add(shapes):
debugprint('union()')
shape = None
for item in shapes:
- if shape is None:
- shape = item
- else:
- shape += item
+ if item is not None:
+ if shape is None:
+ shape = item
+ else:
+ shape += item
return shape
def difference(shape, shapes):
debugprint('difference()')
for item in shapes:
- shape -= item
+ if item is not None:
+ shape -= item
return shape
def intersect(shape1, shape2):
- return sl.intersection()(shape1, shape2)
-
+ if shape2 is not None:
+ return sl.intersection()(shape1, shape2)
+ else:
+ return shape1
def hull_from_points(points):
return sl.hull()(*points)
diff --git a/src/run_config.json b/src/run_config.json
index 48bde38..3b1da65 100644
--- a/src/run_config.json
+++ b/src/run_config.json
@@ -2,7 +2,7 @@
"ENGINE": "solid",
"save_dir": ".",
"config_name": "DM",
- "show_caps": true,
+ "show_caps": false,
"show_pcbs": false,
"nrows": 5,
"ncols": 6,
@@ -20,7 +20,10 @@
7
],
"keyboard_z_offset": 11,
- "thumb_style": "TRACKBALL_ORBYL",
+ "web_thickness": 4.0,
+ "post_size": 0.1,
+ "post_adj": 0,
+ "thumb_style": "CARBONFET",
"default_1U_cluster": true,
"minidox_Usize": 1.6,
"thumb_plate_tr_rotation": 0.0,
@@ -116,6 +119,10 @@
"tbcj_thickness": 2,
"tbcj_outer_diameter": 53,
"trackball_modular": false,
+ "trackball_modular_lip_width": 3.0,
+ "trackball_modular_ball_height": 3.0,
+ "trackball_modular_ring_height": 10.0,
+ "trackball_modular_clearance": 0.5,
"trackball_Usize": 1.5,
"ball_side": "right",
"ball_diameter": 34.0,
@@ -308,9 +315,6 @@
"oled_clip_z_gap": 0.2
}
},
- "web_thickness": 4.0,
- "post_size": 0.1,
- "post_adj": 0,
"screws_offset": "INSIDE",
"screw_insert_height": 3.8,
"screw_insert_bottom_radius": 2.655,
@@ -318,11 +322,45 @@
"wire_post_height": 7,
"wire_post_overhang": 3.5,
"wire_post_diameter": 2.6,
- "controller_mount_type": "EXTERNAL",
+ "controller_mount_type": "PCB_MOUNT",
"external_holder_height": 12.5,
"external_holder_width": 28.75,
"external_holder_xoffset": -5.0,
"external_holder_yoffset": -4.5,
+ "pcb_mount_ref_y_offset": -5,
+ "pcb_holder_size": [
+ 34.6,
+ 7,
+ 4
+ ],
+ "pcb_holder_x_offset": 8.9,
+ "pcb_usb_hole_x_offset": 15,
+ "pcb_usb_hole_z_offset": 4.5,
+ "pcb_usb_hole_size": [
+ 7.5,
+ 10.0,
+ 4
+ ],
+ "wall_thinner_size": [
+ 34,
+ 7,
+ 10
+ ],
+ "trrs_hole_size": [
+ 3,
+ 20
+ ],
+ "trrs_z_offset": 1.5,
+ "pcb_screw_hole_size": [
+ 0.5,
+ 10
+ ],
+ "pcb_screw_x_offsets": [
+ -5.5,
+ 7.75,
+ 22
+ ],
+ "pcb_screw_y_offset": -2,
"screw_hole_diameter": 2,
"base_thickness": 3.0,
"base_offset": 3.0,