New simplified version

This commit is contained in:
Chris Greening 2022-10-09 20:46:45 +01:00
parent 2e01023c11
commit fcb3b55df7
2 changed files with 296 additions and 215 deletions

View file

@ -12,8 +12,10 @@
"# import matplotlib as plt\n", "# import matplotlib as plt\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"import scipy\n", "import scipy\n",
"from skspatial.objects import LineSegment, Line\n", "from skspatial.objects import LineSegment, Line, Vector\n",
"from enum import Enum" "from enum import Enum\n",
"\n",
"Layer = Enum(\"Layer\", \"FRONT BACK\")"
] ]
}, },
{ {
@ -27,11 +29,67 @@
"STATOR_HOLE_RADIUS = 5\n", "STATOR_HOLE_RADIUS = 5\n",
"TRACK_WIDTH = 0.127\n", "TRACK_WIDTH = 0.127\n",
"TRACK_SPACING = 0.127\n", "TRACK_SPACING = 0.127\n",
"TURNS = 13\n", "TURNS = 18\n",
"STATOR_RADIUS = 18\n", "STATOR_RADIUS = 18\n",
"COIL_CENTER_RADIUS = 11\n", "COIL_CENTER_RADIUS = 11.5\n",
"USE_SPIRAL = False\n", "# where to place the pins\n",
"Layer = Enum(\"Layer\", \"FRONT BACK\")" "CONNECTION_PINS_RADIUS = 16\n",
"USE_SPIRAL = False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# get the point on an arc at the given angle\n",
"def get_arc_point(angle, radius):\n",
" return (\n",
" radius * np.cos(np.deg2rad(angle)),\n",
" radius * np.sin(np.deg2rad(angle)),\n",
" )\n",
"\n",
"\n",
"# draw an arc\n",
"def draw_arc(start_angle, end_angle, radius, step=10):\n",
" points = []\n",
" for angle in np.arange(start_angle, end_angle + step, step):\n",
" x = radius * np.cos(np.deg2rad(angle))\n",
" y = radius * np.sin(np.deg2rad(angle))\n",
" points.append((x, y))\n",
" return points\n",
"\n",
"\n",
"# roate the points by the required angle\n",
"def rotate(points, angle):\n",
" return [\n",
" [\n",
" x * np.cos(np.deg2rad(angle)) - y * np.sin(np.deg2rad(angle)),\n",
" x * np.sin(np.deg2rad(angle)) + y * np.cos(np.deg2rad(angle)),\n",
" ]\n",
" for x, y in points\n",
" ]\n",
"\n",
"\n",
"# move the points out to the distance at the requited angle\n",
"def translate(points, distance, angle):\n",
" return [\n",
" [\n",
" x + distance * np.cos(np.deg2rad(angle)),\n",
" y + distance * np.sin(np.deg2rad(angle)),\n",
" ]\n",
" for x, y in points\n",
" ]\n",
"\n",
"\n",
"# flip the y coordinate\n",
"def flip_y(points):\n",
" return [[x, -y] for x, y in points]\n",
"\n",
"\n",
"def flip_x(points):\n",
" return [[-x, y] for x, y in points]"
] ]
}, },
{ {
@ -47,7 +105,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"template = [(-1.5, -0.1), (1.5, -2), (2.0, -1), (2.0, 1), (1.5, 2), (-1.5, 0.1)]" "template_f = [\n",
" (-0.6, 0),\n",
" (-0.6, -0.6),\n",
" (0.5, -1.2),\n",
" (0.95, -0.4),\n",
" (0.95, 0),\n",
" (0.95, 0.4),\n",
" (0.5, 1.2),\n",
" (-0.6, 0.6),\n",
"]\n",
"\n",
"template_b = []\n",
"for i in range(len(template_f)):\n",
" template_b.append(template_f[len(template_f) - i - len(template_f) // 2])\n",
"template_b = flip_x(template_b)"
] ]
}, },
{ {
@ -57,10 +129,11 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# plot the template shape wrapping around to the first point\n", "# plot the template shape wrapping around to the first point\n",
"plt.plot(\n", "df = pd.DataFrame(template_f + [template_f[0]], columns=[\"x\", \"y\"])\n",
" [x for x, y in template] + [template[0][0]],\n", "ax = df.plot.line(x=\"x\", y=\"y\", color=\"blue\")\n",
" [y for x, y in template] + [template[0][1]],\n", "ax.axis(\"equal\")\n",
")" "df = pd.DataFrame(template_b + [template_b[0]], columns=[\"x\", \"y\"])\n",
"ax = df.plot.line(x=\"x\", y=\"y\", color=\"red\", ax=ax)"
] ]
}, },
{ {
@ -69,105 +142,66 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# this speeds things up dramatically as we only have to compute the line intersections once\n", "def calculate_point(point, point1, point2, spacing, turn, layer):\n",
"# there are probably much faster ways of doing this - we're just doing a brute force search\n", " reference_vector = Vector([-100, 0])\n",
"# for the intersections - consult algorithms from games for inspiration...\n", " angle = np.rad2deg(Vector(point).angle_between(reference_vector))\n",
"def get_template_point_cache(template):\n", " if point[1] > 0:\n",
" # sweep a line from the origin through 360 degress times the number of turns in 1 degree increments\n", " angle = 360 - angle\n",
" # and find the intersection points with the template shape\n", " vector = Vector(point1) - Vector(point2)\n",
" cache = {}\n", " normal = vector / np.linalg.norm(vector)\n",
" for angle in np.arange(0, 360 + 1, 1):\n", " # rotate the vector 90 degrees\n",
" line = LineSegment(\n", " normal = np.array([-normal[1], normal[0]])\n",
" np.array([0, 0]),\n", " # move the point along the normal vector by the spacing\n",
" np.array(\n", " offset = spacing * (turn * 360 + angle) / 360\n",
" [1000 * np.cos(np.deg2rad(angle)), 1000 * np.sin(np.deg2rad(angle))]\n", " coil_point = point + normal * offset\n",
" ),\n", " return (coil_point[0], coil_point[1])\n",
" )\n",
" for i in range(len(template)):\n",
" segment = LineSegment(\n",
" np.array(template[i]), np.array(template[(i + 1) % len(template)])\n",
" )\n",
" try:\n",
" intersection = line.intersect_line_segment(segment)\n",
" if intersection is not None:\n",
" cache[angle] = (intersection, segment)\n",
" except ValueError:\n",
" try:\n",
" # nudge the angle slightly\n",
" new_angle = angle + 0.1\n",
" line = LineSegment(\n",
" np.array([0, 0]),\n",
" np.array(\n",
" [\n",
" 1000 * np.cos(np.deg2rad(new_angle)),\n",
" 1000 * np.sin(np.deg2rad(new_angle)),\n",
" ]\n",
" ),\n",
" )\n",
" intersection = line.intersect_line_segment(segment)\n",
" if intersection is not None:\n",
" cache[angle] = (intersection, segment)\n",
" except ValueError:\n",
" pass\n",
" return cache\n",
"\n", "\n",
"\n", "\n",
"def get_point(angle, template, layer, spacing, cache):\n", "def get_points(template, turns, spacing, layer=Layer.FRONT):\n",
" if layer == Layer.BACK:\n",
" angle = angle + 180\n",
" intersection, segment = cache[angle % 360]\n",
" return intersection, segment\n",
"\n",
"\n",
"# get the points in a coil shape\n",
"# Use reverse for bottom layer (basically flips the y coordinate so that the coil goes in the opposite direction)\n",
"# Also rotates the endpoints by 90 degress so that the exit point on the bottom layer is to the left hand side\n",
"def get_points(template, turns, spacing, layer=Layer.FRONT, cache=None):\n",
" if cache is None:\n",
" cache = get_template_point_cache(template)\n",
" coil_points = []\n", " coil_points = []\n",
" last_segment = None\n", " reference_vector = Vector([-100, 0])\n",
" for angle in np.arange(0, 360 * turns + 1, 1):\n", " template_index = 0\n",
" offset = spacing * angle / 360\n", " template_length = len(template)\n",
" intersection, segment = get_point(angle, template, layer, spacing, cache)\n", " for turn in range(turns * template_length):\n",
" vector = np.array(segment.point_a) - np.array(segment.point_b)\n", " point1 = template[template_index % template_length]\n",
" normal = vector / np.linalg.norm(vector)\n", " point2 = template[(template_index + 1) % template_length]\n",
" # rotate the vector 90 degrees\n", "\n",
" normal = np.array([-normal[1], normal[0]])\n", " # calculate the new positions of the points\n",
" # move the intersection point along the normal vector by the spacing\n", " coil_point1 = calculate_point(\n",
" coil_point = intersection + normal * offset\n", " point1, point1, point2, spacing, template_index // template_length, layer\n",
" if layer == Layer.BACK:\n", " )\n",
" coil_points.append((coil_point[0], -coil_point[1], segment))\n", " coil_point2 = calculate_point(\n",
" else:\n", " point2,\n",
" coil_points.append((coil_point[0], coil_point[1], segment))\n", " point1,\n",
" # run through the generated coil points and where the line segments change add a point that is the intersection of the previous and next lines\n", " point2,\n",
" # this prevents any corner cutting\n", " spacing,\n",
" points = []\n", " (template_index + 1) // template_length,\n",
" last_segment = coil_points[0][2]\n", " layer,\n",
" for i in range(len(coil_points)):\n", " )\n",
" x, y, segment = coil_points[i]\n", " # add an intermediate point which is the intersection of this new line with the previous line (if there is one)\n",
" same_segment = (\n", " if len(coil_points) >= 2:\n",
" (last_segment.point_a == segment.point_a).all()\n",
" and (last_segment.point_b == segment.point_b).all()\n",
" ).all()\n",
" if (not same_segment) and i > 2 and i < len(coil_points) - 2:\n",
" # create a line from the previous two points\n", " # create a line from the previous two points\n",
" line = Line(\n", " line1 = Line(\n",
" np.array(coil_points[i - 2][0:2]),\n", " coil_points[len(coil_points) - 2],\n",
" np.array(coil_points[i - 2][0:2]) - np.array(coil_points[i - 1][0:2]),\n", " np.array(coil_points[len(coil_points) - 1])\n",
" - np.array(coil_points[len(coil_points) - 2]),\n",
" )\n", " )\n",
" # create a line from the next two points\n", " # create a line from the two new points\n",
" line2 = Line(\n", " line2 = Line(\n",
" np.array(coil_points[i][0:2]),\n", " np.array(coil_point1),\n",
" np.array(coil_points[i][0:2]) - np.array(coil_points[i + 1][0:2]),\n", " np.array(np.array(coil_point1) - np.array(coil_point2)),\n",
" )\n", " )\n",
" # find the intersection of the two lines\n", " # find the intersection of the two lines\n",
" intersection = line.intersect_line(line2)\n", " try:\n",
" # add the intersection point to the list of points\n", " intersection = line1.intersect_line(line2)\n",
" points.append(intersection)\n", " coil_points.append(intersection)\n",
" last_segment = segment\n", " except:\n",
" points.append((x, y))\n", " pass\n",
" return points\n", " coil_points.append(coil_point1)\n",
" coil_points.append(coil_point2)\n",
"\n",
" template_index = template_index + 1\n",
" return coil_points\n",
"\n", "\n",
"\n", "\n",
"def optimize_points(points):\n", "def optimize_points(points):\n",
@ -209,15 +243,6 @@
" return chaikin(smoothed, iterations - 1)" " return chaikin(smoothed, iterations - 1)"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cache = get_template_point_cache(template)"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@ -225,15 +250,30 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"if not USE_SPIRAL:\n", "if not USE_SPIRAL:\n",
" points_f = get_points(\n", " points_f = chaikin(\n",
" template, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT, cache\n", " optimize_points(\n",
" flip_x(\n",
" get_points(template_b, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT)\n",
" )\n",
" ),\n",
" 2,\n",
" )\n", " )\n",
" points_b = get_points(\n", " points_b = chaikin(\n",
" template, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.BACK, cache\n", " optimize_points(\n",
" get_points(template_f, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.BACK)\n",
" ),\n",
" 2,\n",
" )\n", " )\n",
"\n", "\n",
" points_f = [(0, 0)] + chaikin(optimize_points(points_f), 3)\n", " points_f = [(0, 0)] + points_f\n",
" points_b = [(0, 0)] + chaikin(optimize_points(points_b), 3)\n", " points_b = [(0, 0)] + points_b\n",
"\n",
" df = pd.DataFrame(points_f, columns=[\"x\", \"y\"])\n",
" ax = df.plot.line(x=\"x\", y=\"y\", color=\"blue\")\n",
" ax.axis(\"equal\")\n",
" df = pd.DataFrame(points_b, columns=[\"x\", \"y\"])\n",
" ax = df.plot.line(x=\"x\", y=\"y\", color=\"red\", ax=ax)\n",
"\n",
" print(\"Track points\", len(points_f), len(points_b))\n", " print(\"Track points\", len(points_f), len(points_b))\n",
"else:\n", "else:\n",
" print(\"Using spiral\")" " print(\"Using spiral\")"
@ -276,10 +316,10 @@
"source": [ "source": [
"if USE_SPIRAL:\n", "if USE_SPIRAL:\n",
" points_f = get_spiral(\n", " points_f = get_spiral(\n",
" TURNS, VIA_DIAM + TRACK_SPACING, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT\n", " TURNS, VIA_DIAM / 2 + TRACK_SPACING, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT\n",
" )\n", " )\n",
" points_b = get_spiral(\n", " points_b = get_spiral(\n",
" TURNS, VIA_DIAM + TRACK_SPACING, TRACK_SPACING + TRACK_WIDTH, Layer.BACK\n", " TURNS, VIA_DIAM / 2 + TRACK_SPACING, TRACK_SPACING + TRACK_WIDTH, Layer.BACK\n",
" )\n", " )\n",
"\n", "\n",
" points_f = [(0, 0)] + points_f\n", " points_f = [(0, 0)] + points_f\n",
@ -325,69 +365,53 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"vias = []\n", "vias = []\n",
"tracks_f = []\n",
"tracks_b = []\n",
"pads = []\n",
"\n", "\n",
"angle_A = 0\n", "angle_A = 0\n",
"angle_B = 120\n", "angle_B = 120\n",
"angle_C = 240\n", "angle_C = 240\n",
"\n", "\n",
"# get the point on an arc at the given angle\n", "\n",
"def get_arc_point(angle, radius):\n", "def create_pad(radius, angle, name):\n",
" return (\n", " return {\n",
" radius * np.cos(np.deg2rad(angle)),\n", " \"x\": radius * np.cos(np.deg2rad(angle)),\n",
" radius * np.sin(np.deg2rad(angle)),\n", " \"y\": radius * np.sin(np.deg2rad(angle)),\n",
" )\n", " \"name\": name,\n",
" }\n",
"\n", "\n",
"\n", "\n",
"# draw an arc\n", "# create the pads at CONNECTION_PINS radius - 2 for each of the coils, A, B and C\n",
"def draw_arc(start_angle, end_angle, radius, step=10):\n", "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_A - 30, \"A\"))\n",
" points = []\n", "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_A + 30, \"A\"))\n",
" for angle in np.arange(start_angle, end_angle + step, step):\n",
" x = radius * np.cos(np.deg2rad(angle))\n",
" y = radius * np.sin(np.deg2rad(angle))\n",
" points.append((x, y))\n",
" return points\n",
"\n", "\n",
"pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_B - 30, \"B\"))\n",
"pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_B + 30, \"B\"))\n",
"\n", "\n",
"# roate the points by the required angle\n", "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_C - 30, \"C\"))\n",
"def rotate(points, angle):\n", "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_C + 30, \"C\"))\n",
" return [\n",
" [\n",
" x * np.cos(np.deg2rad(angle)) - y * np.sin(np.deg2rad(angle)),\n",
" x * np.sin(np.deg2rad(angle)) + y * np.cos(np.deg2rad(angle)),\n",
" ]\n",
" for x, y in points\n",
" ]\n",
"\n",
"\n",
"# move the points out to the distance at the requited angle\n",
"def translate(points, distance, angle):\n",
" return [\n",
" [\n",
" x + distance * np.cos(np.deg2rad(angle)),\n",
" y + distance * np.sin(np.deg2rad(angle)),\n",
" ]\n",
" for x, y in points\n",
" ]\n",
"\n", "\n",
"\n", "\n",
"def create_via(point):\n", "def create_via(point):\n",
" return {\"x\": point[0], \"y\": point[1]}\n", " return {\"x\": point[0], \"y\": point[1]}\n",
"\n", "\n",
"\n", "\n",
"# flip the y coordinate\n",
"def flip(points):\n",
" return [[x, -y] for x, y in points]\n",
"\n",
"\n",
"# the main coils\n", "# the main coils\n",
"coil_A_f = translate(rotate(points_f, angle_A), COIL_CENTER_RADIUS, angle_A)\n", "coil_A_f = translate(rotate(points_f, angle_A), COIL_CENTER_RADIUS, angle_A)\n",
"coil_A_b = translate(rotate(points_b, angle_A), COIL_CENTER_RADIUS, angle_A)\n", "coil_A_b = translate(rotate(points_b, angle_A), COIL_CENTER_RADIUS, angle_A)\n",
"tracks_f.append(coil_A_f)\n",
"tracks_b.append(coil_A_b)\n",
"\n", "\n",
"coil_B_f = translate(rotate(points_f, angle_B), COIL_CENTER_RADIUS, angle_B)\n", "coil_B_f = translate(rotate(points_f, angle_B), COIL_CENTER_RADIUS, angle_B)\n",
"coil_B_b = translate(rotate(points_b, angle_B), COIL_CENTER_RADIUS, angle_B)\n", "coil_B_b = translate(rotate(points_b, angle_B), COIL_CENTER_RADIUS, angle_B)\n",
"tracks_f.append(coil_B_f)\n",
"tracks_b.append(coil_B_b)\n",
"\n", "\n",
"coil_C_f = translate(rotate(points_f, angle_C), COIL_CENTER_RADIUS, angle_C)\n", "coil_C_f = translate(rotate(points_f, angle_C), COIL_CENTER_RADIUS, angle_C)\n",
"coil_C_b = translate(rotate(points_b, angle_C), COIL_CENTER_RADIUS, angle_C)\n", "coil_C_b = translate(rotate(points_b, angle_C), COIL_CENTER_RADIUS, angle_C)\n",
"tracks_f.append(coil_C_f)\n",
"tracks_b.append(coil_C_b)\n",
"\n", "\n",
"# the opposite coils - for more power!\n", "# the opposite coils - for more power!\n",
"angle_A_opp = angle_A + 180\n", "angle_A_opp = angle_A + 180\n",
@ -395,25 +419,31 @@
"angle_C_opp = angle_C + 180\n", "angle_C_opp = angle_C + 180\n",
"\n", "\n",
"coil_A_opp_f = translate(\n", "coil_A_opp_f = translate(\n",
" rotate(flip(points_f), angle_A_opp), COIL_CENTER_RADIUS, angle_A_opp\n", " rotate(flip_y(points_f), angle_A_opp), COIL_CENTER_RADIUS, angle_A_opp\n",
")\n", ")\n",
"coil_A_opp_b = translate(\n", "coil_A_opp_b = translate(\n",
" rotate(flip(points_b), angle_A_opp), COIL_CENTER_RADIUS, angle_A_opp\n", " rotate(flip_y(points_b), angle_A_opp), COIL_CENTER_RADIUS, angle_A_opp\n",
")\n", ")\n",
"tracks_f.append(coil_A_opp_f)\n",
"tracks_b.append(coil_A_opp_b)\n",
"\n", "\n",
"coil_B_opp_f = translate(\n", "coil_B_opp_f = translate(\n",
" rotate(flip(points_f), angle_B_opp), COIL_CENTER_RADIUS, angle_B_opp\n", " rotate(flip_y(points_f), angle_B_opp), COIL_CENTER_RADIUS, angle_B_opp\n",
")\n", ")\n",
"coil_B_opp_b = translate(\n", "coil_B_opp_b = translate(\n",
" rotate(flip(points_b), angle_B_opp), COIL_CENTER_RADIUS, angle_B_opp\n", " rotate(flip_y(points_b), angle_B_opp), COIL_CENTER_RADIUS, angle_B_opp\n",
")\n", ")\n",
"tracks_f.append(coil_B_opp_f)\n",
"tracks_b.append(coil_B_opp_b)\n",
"\n", "\n",
"coil_C_opp_f = translate(\n", "coil_C_opp_f = translate(\n",
" rotate(flip(points_f), angle_C_opp), COIL_CENTER_RADIUS, angle_C_opp\n", " rotate(flip_y(points_f), angle_C_opp), COIL_CENTER_RADIUS, angle_C_opp\n",
")\n", ")\n",
"coil_C_opp_b = translate(\n", "coil_C_opp_b = translate(\n",
" rotate(flip(points_b), angle_C_opp), COIL_CENTER_RADIUS, angle_C_opp\n", " rotate(flip_y(points_b), angle_C_opp), COIL_CENTER_RADIUS, angle_C_opp\n",
")\n", ")\n",
"tracks_f.append(coil_C_opp_f)\n",
"tracks_b.append(coil_C_opp_b)\n",
"\n", "\n",
"# connect the front and back coils together\n", "# connect the front and back coils together\n",
"vias.append(create_via(get_arc_point(angle_A, COIL_CENTER_RADIUS)))\n", "vias.append(create_via(get_arc_point(angle_A, COIL_CENTER_RADIUS)))\n",
@ -430,23 +460,32 @@
"coil_B_opp_f.append(get_arc_point(angle_B_opp, common_connection_radius))\n", "coil_B_opp_f.append(get_arc_point(angle_B_opp, common_connection_radius))\n",
"coil_C_opp_f.append(get_arc_point(angle_C_opp, common_connection_radius))\n", "coil_C_opp_f.append(get_arc_point(angle_C_opp, common_connection_radius))\n",
"\n", "\n",
"tracks_b.append(common_coil_connections_b)\n",
"\n",
"vias.append(create_via(get_arc_point(angle_A_opp, common_connection_radius)))\n", "vias.append(create_via(get_arc_point(angle_A_opp, common_connection_radius)))\n",
"vias.append(create_via(get_arc_point(angle_B_opp, common_connection_radius)))\n", "vias.append(create_via(get_arc_point(angle_B_opp, common_connection_radius)))\n",
"vias.append(create_via(get_arc_point(angle_C_opp, common_connection_radius)))\n", "vias.append(create_via(get_arc_point(angle_C_opp, common_connection_radius)))\n",
"\n", "\n",
"# route coil A and coil C round to coil B so we have a good place to connect to them\n", "# connect the coils to the pads\n",
"coil_input_radius = common_connection_radius - (VIA_DIAM / 2 + TRACK_SPACING)\n", "coil_A_f.append(get_arc_point(angle_A, common_connection_radius))\n",
"coil_A_input_connection_b = draw_arc(angle_A, 80, coil_input_radius)\n", "coil_B_f.append(get_arc_point(angle_B, common_connection_radius))\n",
"coil_B_input_connection_f = draw_arc(90, angle_B, coil_input_radius)\n", "coil_C_f.append(get_arc_point(angle_C, common_connection_radius))\n",
"coil_C_input_connection_b = draw_arc(100, angle_C, coil_input_radius)\n",
"\n",
"coil_A_f.append(coil_A_input_connection_b[0])\n",
"coil_B_f.append(get_arc_point(angle_B, coil_input_radius))\n",
"coil_C_f.append(coil_C_input_connection_b[-1])\n",
"\n",
"vias.append(create_via(coil_A_input_connection_b[0]))\n",
"vias.append(create_via(coil_C_input_connection_b[-1]))\n",
"\n", "\n",
"tracks_f.append(\n",
" [get_arc_point(angle_A - 30, CONNECTION_PINS_RADIUS)]\n",
" + draw_arc(angle_A - 30, angle_A + 30, common_connection_radius)\n",
" + [get_arc_point(angle_A + 30, CONNECTION_PINS_RADIUS)]\n",
")\n",
"tracks_f.append(\n",
" [get_arc_point(angle_B - 30, CONNECTION_PINS_RADIUS)]\n",
" + draw_arc(angle_B - 30, angle_B + 30, common_connection_radius)\n",
" + [get_arc_point(angle_B + 30, CONNECTION_PINS_RADIUS)]\n",
")\n",
"tracks_f.append(\n",
" [get_arc_point(angle_C - 30, CONNECTION_PINS_RADIUS)]\n",
" + draw_arc(angle_C - 30, angle_C + 30, common_connection_radius)\n",
" + [get_arc_point(angle_C + 30, CONNECTION_PINS_RADIUS)]\n",
")\n",
"\n", "\n",
"# wires for connecting to opposite coils\n", "# wires for connecting to opposite coils\n",
"connection_radius1 = STATOR_HOLE_RADIUS + (TRACK_SPACING)\n", "connection_radius1 = STATOR_HOLE_RADIUS + (TRACK_SPACING)\n",
@ -463,6 +502,9 @@
"a_connection_f = draw_arc(angle_A + 90, angle_A + 180, connection_radius2)\n", "a_connection_f = draw_arc(angle_A + 90, angle_A + 180, connection_radius2)\n",
"a_connection_b.append(a_connection_f[0])\n", "a_connection_b.append(a_connection_f[0])\n",
"\n", "\n",
"tracks_f.append(a_connection_f)\n",
"tracks_b.append(a_connection_b)\n",
"\n",
"# coil B\n", "# coil B\n",
"coil_B_b.append(get_arc_point(angle_B, connection_radius1))\n", "coil_B_b.append(get_arc_point(angle_B, connection_radius1))\n",
"coil_B_opp_b.append(get_arc_point(angle_B_opp, connection_radius2))\n", "coil_B_opp_b.append(get_arc_point(angle_B_opp, connection_radius2))\n",
@ -470,6 +512,9 @@
"b_connection_f = draw_arc(angle_B + 90, angle_B + 180, connection_radius2)\n", "b_connection_f = draw_arc(angle_B + 90, angle_B + 180, connection_radius2)\n",
"b_connection_b.append(b_connection_f[0])\n", "b_connection_b.append(b_connection_f[0])\n",
"\n", "\n",
"tracks_f.append(b_connection_f)\n",
"tracks_b.append(b_connection_b)\n",
"\n",
"# coil C\n", "# coil C\n",
"coil_C_b.append(get_arc_point(angle_C, connection_radius1))\n", "coil_C_b.append(get_arc_point(angle_C, connection_radius1))\n",
"coil_C_opp_b.append(get_arc_point(angle_C_opp, connection_radius2))\n", "coil_C_opp_b.append(get_arc_point(angle_C_opp, connection_radius2))\n",
@ -477,6 +522,9 @@
"c_connection_f = draw_arc(angle_C + 90, angle_C + 180, connection_radius2)\n", "c_connection_f = draw_arc(angle_C + 90, angle_C + 180, connection_radius2)\n",
"c_connection_b.append(c_connection_f[0])\n", "c_connection_b.append(c_connection_f[0])\n",
"\n", "\n",
"tracks_f.append(c_connection_f)\n",
"tracks_b.append(c_connection_b)\n",
"\n",
"vias.append(create_via(a_connection_f[0]))\n", "vias.append(create_via(a_connection_f[0]))\n",
"vias.append(create_via(b_connection_f[0]))\n", "vias.append(create_via(b_connection_f[0]))\n",
"vias.append(create_via(c_connection_f[0]))\n", "vias.append(create_via(c_connection_f[0]))\n",
@ -506,6 +554,7 @@
" \"viaDrillDiameter\": VIA_DRILL,\n", " \"viaDrillDiameter\": VIA_DRILL,\n",
" },\n", " },\n",
" \"vias\": vias,\n", " \"vias\": vias,\n",
" \"pads\": pads,\n",
" \"silk\": [\n", " \"silk\": [\n",
" {\n", " {\n",
" \"x\": COIL_CENTER_RADIUS * np.cos(np.deg2rad(angle_A)),\n", " \"x\": COIL_CENTER_RADIUS * np.cos(np.deg2rad(angle_A)),\n",
@ -524,38 +573,8 @@
" },\n", " },\n",
" ],\n", " ],\n",
" \"tracks\": {\n", " \"tracks\": {\n",
" \"f\": [\n", " \"f\": [create_track(points) for points in tracks_f],\n",
" create_track(points)\n", " \"b\": [create_track(points) for points in tracks_b],\n",
" for points in [\n",
" coil_A_f,\n",
" coil_A_opp_f,\n",
" coil_B_f,\n",
" coil_B_opp_f,\n",
" coil_C_f,\n",
" coil_C_opp_f,\n",
" a_connection_f,\n",
" b_connection_f,\n",
" c_connection_f,\n",
" coil_B_input_connection_f,\n",
" ]\n",
" ],\n",
" \"b\": [\n",
" create_track(points)\n",
" for points in [\n",
" coil_A_b,\n",
" coil_A_opp_b,\n",
" coil_B_b,\n",
" coil_B_opp_b,\n",
" coil_C_b,\n",
" coil_C_opp_b,\n",
" common_coil_connections_b,\n",
" a_connection_b,\n",
" b_connection_b,\n",
" c_connection_b,\n",
" coil_A_input_connection_b,\n",
" coil_C_input_connection_b,\n",
" ]\n",
" ],\n",
" },\n", " },\n",
"}\n", "}\n",
"\n", "\n",
@ -599,6 +618,51 @@
" fill=True,\n", " fill=True,\n",
" color=\"black\",\n", " color=\"black\",\n",
" )\n", " )\n",
" )\n",
" ax.add_patch(\n",
" plt.Circle(\n",
" (via[\"x\"], via[\"y\"]),\n",
" radius=VIA_DRILL / 2,\n",
" fill=True,\n",
" color=\"white\",\n",
" )\n",
" )\n",
"\n",
"# plot the edge cuts\n",
"ax.add_patch(\n",
" plt.Circle(\n",
" (0, 0),\n",
" radius=STATOR_RADIUS,\n",
" fill=False,\n",
" color=\"yellow\",\n",
" )\n",
")\n",
"ax.add_patch(\n",
" plt.Circle(\n",
" (0, 0),\n",
" radius=STATOR_HOLE_RADIUS,\n",
" fill=False,\n",
" color=\"yellow\",\n",
" )\n",
")\n",
"\n",
"# plot the pads\n",
"for pad in json_result[\"pads\"]:\n",
" ax.add_patch(\n",
" plt.Circle(\n",
" (pad[\"x\"], pad[\"y\"]),\n",
" radius=1.7 / 2,\n",
" fill=True,\n",
" color=\"yellow\",\n",
" )\n",
" )\n",
" ax.add_patch(\n",
" plt.Circle(\n",
" (pad[\"x\"], pad[\"y\"]),\n",
" radius=1.0 / 2,\n",
" fill=True,\n",
" color=\"white\",\n",
" )\n",
" )" " )"
] ]
} }

View file

@ -18,7 +18,7 @@ def create_tracks(board, group, net, layer, thickness, coords):
if net is not None: if net is not None:
track.SetNetCode(net.GetNetCode()) track.SetNetCode(net.GetNetCode())
board.Add(track) board.Add(track)
group.AddItem(track) # group.AddItem(track)
last_x = x last_x = x
last_y = y last_y = y
@ -49,7 +49,7 @@ class CoilPlugin(pcbnew.ActionPlugin):
# put everything in a group to make it easier to manage # put everything in a group to make it easier to manage
pcb_group = pcbnew.PCB_GROUP(board) pcb_group = pcbnew.PCB_GROUP(board)
board.Add(pcb_group) # board.Add(pcb_group)
# create the center hole # create the center hole
arc = pcbnew.PCB_SHAPE(board) arc = pcbnew.PCB_SHAPE(board)
@ -60,7 +60,7 @@ class CoilPlugin(pcbnew.ActionPlugin):
arc.SetLayer(pcbnew.Edge_Cuts) arc.SetLayer(pcbnew.Edge_Cuts)
arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM)) arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM))
board.Add(arc) board.Add(arc)
pcb_group.AddItem(arc) # pcb_group.AddItem(arc)
# create the stator outline # create the stator outline
arc = pcbnew.PCB_SHAPE(board) arc = pcbnew.PCB_SHAPE(board)
@ -71,14 +71,16 @@ class CoilPlugin(pcbnew.ActionPlugin):
arc.SetLayer(pcbnew.Edge_Cuts) arc.SetLayer(pcbnew.Edge_Cuts)
arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM)) arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM))
board.Add(arc) board.Add(arc)
pcb_group.AddItem(arc) # pcb_group.AddItem(arc)
# create tracks # create tracks
for track in coil_data["tracks"]["f"]: for track in coil_data["tracks"]["f"]:
# find the matching net for the track # find the matching net for the track
net = board.FindNet("coils") net = board.FindNet("coils")
if net is None: if net is None:
raise "Net not found: {}".format(track["net"]) net = pcbnew.NETINFO_ITEM(board, "coils")
board.Add(net)
# raise "Net not found: {}".format(track["net"])
create_tracks( create_tracks(
board, pcb_group, net, pcbnew.F_Cu, track_width, track board, pcb_group, net, pcbnew.F_Cu, track_width, track
) )
@ -98,7 +100,21 @@ class CoilPlugin(pcbnew.ActionPlugin):
pcb_via.SetDrill(int(via_drill_diameter * 1e6)) pcb_via.SetDrill(int(via_drill_diameter * 1e6))
pcb_via.SetNetCode(net.GetNetCode()) pcb_via.SetNetCode(net.GetNetCode())
board.Add(pcb_via) board.Add(pcb_via)
pcb_group.AddItem(pcb_via) # pcb_group.AddItem(pcb_via)
# create the pads
for pad in coil_data["pads"]:
module = pcbnew.FOOTPRINT(board)
board.Add(module)
pcb_pad = pcbnew.PAD(module)
pcb_pad.SetSize(pcbnew.wxSizeMM(1.7, 1.7))
pcb_pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
pcb_pad.SetAttribute(pcbnew.PAD_ATTRIB_PTH)
pcb_pad.SetLayerSet(pcb_pad.PTHMask())
pcb_pad.SetDrillSize(pcbnew.wxSizeMM(1.0, 1.0))
pcb_pad.SetPosition(pcbnew.wxPointMM(pad["x"], pad["y"]))
pcb_pad.SetNetCode(net.GetNetCode())
module.Add(pcb_pad)
# create any silk screen # create any silk screen
for text in coil_data["silk"]: for text in coil_data["silk"]:
@ -109,7 +125,8 @@ class CoilPlugin(pcbnew.ActionPlugin):
pcb_txt.SetTextSize(pcbnew.wxSize(5000000, 5000000)) pcb_txt.SetTextSize(pcbnew.wxSize(5000000, 5000000))
pcb_txt.SetLayer(pcbnew.F_SilkS) pcb_txt.SetLayer(pcbnew.F_SilkS)
board.Add(pcb_txt) board.Add(pcb_txt)
pcb_group.AddItem(pcb_txt) # pcb_group.AddItem(pcb_txt)
CoilPlugin().register() # Instantiate and register to Pcbnew]) CoilPlugin().register() # Instantiate and register to Pcbnew])