diff --git a/coil_version2.ipynb b/coil_generator.ipynb similarity index 62% rename from coil_version2.ipynb rename to coil_generator.ipynb index e8bf414..5032697 100644 --- a/coil_version2.ipynb +++ b/coil_generator.ipynb @@ -12,8 +12,10 @@ "# import matplotlib as plt\n", "import matplotlib.pyplot as plt\n", "import scipy\n", - "from skspatial.objects import LineSegment, Line\n", - "from enum import Enum" + "from skspatial.objects import LineSegment, Line, Vector\n", + "from enum import Enum\n", + "\n", + "Layer = Enum(\"Layer\", \"FRONT BACK\")" ] }, { @@ -27,11 +29,67 @@ "STATOR_HOLE_RADIUS = 5\n", "TRACK_WIDTH = 0.127\n", "TRACK_SPACING = 0.127\n", - "TURNS = 13\n", + "TURNS = 18\n", "STATOR_RADIUS = 18\n", - "COIL_CENTER_RADIUS = 11\n", - "USE_SPIRAL = False\n", - "Layer = Enum(\"Layer\", \"FRONT BACK\")" + "COIL_CENTER_RADIUS = 11.5\n", + "# where to place the pins\n", + "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": {}, "outputs": [], "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": [], "source": [ "# plot the template shape wrapping around to the first point\n", - "plt.plot(\n", - " [x for x, y in template] + [template[0][0]],\n", - " [y for x, y in template] + [template[0][1]],\n", - ")" + "df = pd.DataFrame(template_f + [template_f[0]], columns=[\"x\", \"y\"])\n", + "ax = df.plot.line(x=\"x\", y=\"y\", color=\"blue\")\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": {}, "outputs": [], "source": [ - "# this speeds things up dramatically as we only have to compute the line intersections once\n", - "# there are probably much faster ways of doing this - we're just doing a brute force search\n", - "# for the intersections - consult algorithms from games for inspiration...\n", - "def get_template_point_cache(template):\n", - " # sweep a line from the origin through 360 degress times the number of turns in 1 degree increments\n", - " # and find the intersection points with the template shape\n", - " cache = {}\n", - " for angle in np.arange(0, 360 + 1, 1):\n", - " line = LineSegment(\n", - " np.array([0, 0]),\n", - " np.array(\n", - " [1000 * np.cos(np.deg2rad(angle)), 1000 * np.sin(np.deg2rad(angle))]\n", - " ),\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", + "def calculate_point(point, point1, point2, spacing, turn, layer):\n", + " reference_vector = Vector([-100, 0])\n", + " angle = np.rad2deg(Vector(point).angle_between(reference_vector))\n", + " if point[1] > 0:\n", + " angle = 360 - angle\n", + " vector = Vector(point1) - Vector(point2)\n", + " normal = vector / np.linalg.norm(vector)\n", + " # rotate the vector 90 degrees\n", + " normal = np.array([-normal[1], normal[0]])\n", + " # move the point along the normal vector by the spacing\n", + " offset = spacing * (turn * 360 + angle) / 360\n", + " coil_point = point + normal * offset\n", + " return (coil_point[0], coil_point[1])\n", "\n", "\n", - "def get_point(angle, template, layer, spacing, cache):\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", + "def get_points(template, turns, spacing, layer=Layer.FRONT):\n", " coil_points = []\n", - " last_segment = None\n", - " for angle in np.arange(0, 360 * turns + 1, 1):\n", - " offset = spacing * angle / 360\n", - " intersection, segment = get_point(angle, template, layer, spacing, cache)\n", - " vector = np.array(segment.point_a) - np.array(segment.point_b)\n", - " normal = vector / np.linalg.norm(vector)\n", - " # rotate the vector 90 degrees\n", - " normal = np.array([-normal[1], normal[0]])\n", - " # move the intersection point along the normal vector by the spacing\n", - " coil_point = intersection + normal * offset\n", - " if layer == Layer.BACK:\n", - " coil_points.append((coil_point[0], -coil_point[1], segment))\n", - " else:\n", - " coil_points.append((coil_point[0], coil_point[1], segment))\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", - " # this prevents any corner cutting\n", - " points = []\n", - " last_segment = coil_points[0][2]\n", - " for i in range(len(coil_points)):\n", - " x, y, segment = coil_points[i]\n", - " same_segment = (\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", + " reference_vector = Vector([-100, 0])\n", + " template_index = 0\n", + " template_length = len(template)\n", + " for turn in range(turns * template_length):\n", + " point1 = template[template_index % template_length]\n", + " point2 = template[(template_index + 1) % template_length]\n", + "\n", + " # calculate the new positions of the points\n", + " coil_point1 = calculate_point(\n", + " point1, point1, point2, spacing, template_index // template_length, layer\n", + " )\n", + " coil_point2 = calculate_point(\n", + " point2,\n", + " point1,\n", + " point2,\n", + " spacing,\n", + " (template_index + 1) // template_length,\n", + " layer,\n", + " )\n", + " # add an intermediate point which is the intersection of this new line with the previous line (if there is one)\n", + " if len(coil_points) >= 2:\n", " # create a line from the previous two points\n", - " line = Line(\n", - " np.array(coil_points[i - 2][0:2]),\n", - " np.array(coil_points[i - 2][0:2]) - np.array(coil_points[i - 1][0:2]),\n", + " line1 = Line(\n", + " coil_points[len(coil_points) - 2],\n", + " np.array(coil_points[len(coil_points) - 1])\n", + " - np.array(coil_points[len(coil_points) - 2]),\n", " )\n", - " # create a line from the next two points\n", + " # create a line from the two new points\n", " line2 = Line(\n", - " np.array(coil_points[i][0:2]),\n", - " np.array(coil_points[i][0:2]) - np.array(coil_points[i + 1][0:2]),\n", + " np.array(coil_point1),\n", + " np.array(np.array(coil_point1) - np.array(coil_point2)),\n", " )\n", " # find the intersection of the two lines\n", - " intersection = line.intersect_line(line2)\n", - " # add the intersection point to the list of points\n", - " points.append(intersection)\n", - " last_segment = segment\n", - " points.append((x, y))\n", - " return points\n", + " try:\n", + " intersection = line1.intersect_line(line2)\n", + " coil_points.append(intersection)\n", + " except:\n", + " pass\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", "def optimize_points(points):\n", @@ -209,15 +243,6 @@ " return chaikin(smoothed, iterations - 1)" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cache = get_template_point_cache(template)" - ] - }, { "cell_type": "code", "execution_count": null, @@ -225,15 +250,30 @@ "outputs": [], "source": [ "if not USE_SPIRAL:\n", - " points_f = get_points(\n", - " template, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT, cache\n", + " points_f = chaikin(\n", + " optimize_points(\n", + " flip_x(\n", + " get_points(template_b, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.FRONT)\n", + " )\n", + " ),\n", + " 2,\n", " )\n", - " points_b = get_points(\n", - " template, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.BACK, cache\n", + " points_b = chaikin(\n", + " optimize_points(\n", + " get_points(template_f, TURNS, TRACK_SPACING + TRACK_WIDTH, Layer.BACK)\n", + " ),\n", + " 2,\n", " )\n", "\n", - " points_f = [(0, 0)] + chaikin(optimize_points(points_f), 3)\n", - " points_b = [(0, 0)] + chaikin(optimize_points(points_b), 3)\n", + " points_f = [(0, 0)] + points_f\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", "else:\n", " print(\"Using spiral\")" @@ -276,10 +316,10 @@ "source": [ "if USE_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", " 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", " points_f = [(0, 0)] + points_f\n", @@ -325,69 +365,53 @@ "outputs": [], "source": [ "vias = []\n", + "tracks_f = []\n", + "tracks_b = []\n", + "pads = []\n", "\n", "angle_A = 0\n", "angle_B = 120\n", "angle_C = 240\n", "\n", - "# 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", + "def create_pad(radius, angle, name):\n", + " return {\n", + " \"x\": radius * np.cos(np.deg2rad(angle)),\n", + " \"y\": radius * np.sin(np.deg2rad(angle)),\n", + " \"name\": name,\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", + "# create the pads at CONNECTION_PINS radius - 2 for each of the coils, A, B and C\n", + "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_A - 30, \"A\"))\n", + "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_A + 30, \"A\"))\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", - "# 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", + "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_C - 30, \"C\"))\n", + "pads.append(create_pad(CONNECTION_PINS_RADIUS, angle_C + 30, \"C\"))\n", "\n", "\n", "def create_via(point):\n", " return {\"x\": point[0], \"y\": point[1]}\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", "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", + "tracks_f.append(coil_A_f)\n", + "tracks_b.append(coil_A_b)\n", "\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", + "tracks_f.append(coil_B_f)\n", + "tracks_b.append(coil_B_b)\n", "\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", + "tracks_f.append(coil_C_f)\n", + "tracks_b.append(coil_C_b)\n", "\n", "# the opposite coils - for more power!\n", "angle_A_opp = angle_A + 180\n", @@ -395,25 +419,31 @@ "angle_C_opp = angle_C + 180\n", "\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", "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", + "tracks_f.append(coil_A_opp_f)\n", + "tracks_b.append(coil_A_opp_b)\n", "\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", "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", + "tracks_f.append(coil_B_opp_f)\n", + "tracks_b.append(coil_B_opp_b)\n", "\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", "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", + "tracks_f.append(coil_C_opp_f)\n", + "tracks_b.append(coil_C_opp_b)\n", "\n", "# connect the front and back coils together\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_C_opp_f.append(get_arc_point(angle_C_opp, common_connection_radius))\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_B_opp, common_connection_radius)))\n", "vias.append(create_via(get_arc_point(angle_C_opp, common_connection_radius)))\n", "\n", - "# route coil A and coil C round to coil B so we have a good place to connect to them\n", - "coil_input_radius = common_connection_radius - (VIA_DIAM / 2 + TRACK_SPACING)\n", - "coil_A_input_connection_b = draw_arc(angle_A, 80, coil_input_radius)\n", - "coil_B_input_connection_f = draw_arc(90, angle_B, coil_input_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", + "# connect the coils to the pads\n", + "coil_A_f.append(get_arc_point(angle_A, common_connection_radius))\n", + "coil_B_f.append(get_arc_point(angle_B, common_connection_radius))\n", + "coil_C_f.append(get_arc_point(angle_C, common_connection_radius))\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", "# wires for connecting to opposite coils\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_b.append(a_connection_f[0])\n", "\n", + "tracks_f.append(a_connection_f)\n", + "tracks_b.append(a_connection_b)\n", + "\n", "# coil B\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", @@ -470,6 +512,9 @@ "b_connection_f = draw_arc(angle_B + 90, angle_B + 180, connection_radius2)\n", "b_connection_b.append(b_connection_f[0])\n", "\n", + "tracks_f.append(b_connection_f)\n", + "tracks_b.append(b_connection_b)\n", + "\n", "# coil C\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", @@ -477,6 +522,9 @@ "c_connection_f = draw_arc(angle_C + 90, angle_C + 180, connection_radius2)\n", "c_connection_b.append(c_connection_f[0])\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(b_connection_f[0]))\n", "vias.append(create_via(c_connection_f[0]))\n", @@ -506,6 +554,7 @@ " \"viaDrillDiameter\": VIA_DRILL,\n", " },\n", " \"vias\": vias,\n", + " \"pads\": pads,\n", " \"silk\": [\n", " {\n", " \"x\": COIL_CENTER_RADIUS * np.cos(np.deg2rad(angle_A)),\n", @@ -524,38 +573,8 @@ " },\n", " ],\n", " \"tracks\": {\n", - " \"f\": [\n", - " create_track(points)\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", + " \"f\": [create_track(points) for points in tracks_f],\n", + " \"b\": [create_track(points) for points in tracks_b],\n", " },\n", "}\n", "\n", @@ -599,6 +618,51 @@ " fill=True,\n", " color=\"black\",\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", " )" ] } diff --git a/coil_plugin.py b/coil_plugin.py index 2a7f6f4..cc5a124 100644 --- a/coil_plugin.py +++ b/coil_plugin.py @@ -18,7 +18,7 @@ def create_tracks(board, group, net, layer, thickness, coords): if net is not None: track.SetNetCode(net.GetNetCode()) board.Add(track) - group.AddItem(track) + # group.AddItem(track) last_x = x last_y = y @@ -49,7 +49,7 @@ class CoilPlugin(pcbnew.ActionPlugin): # put everything in a group to make it easier to manage pcb_group = pcbnew.PCB_GROUP(board) - board.Add(pcb_group) + # board.Add(pcb_group) # create the center hole arc = pcbnew.PCB_SHAPE(board) @@ -60,7 +60,7 @@ class CoilPlugin(pcbnew.ActionPlugin): arc.SetLayer(pcbnew.Edge_Cuts) arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM)) board.Add(arc) - pcb_group.AddItem(arc) + # pcb_group.AddItem(arc) # create the stator outline arc = pcbnew.PCB_SHAPE(board) @@ -71,14 +71,16 @@ class CoilPlugin(pcbnew.ActionPlugin): arc.SetLayer(pcbnew.Edge_Cuts) arc.SetWidth(int(0.1 * pcbnew.IU_PER_MM)) board.Add(arc) - pcb_group.AddItem(arc) + # pcb_group.AddItem(arc) # create tracks for track in coil_data["tracks"]["f"]: # find the matching net for the track net = board.FindNet("coils") 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( 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.SetNetCode(net.GetNetCode()) 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 for text in coil_data["silk"]: @@ -109,7 +125,8 @@ class CoilPlugin(pcbnew.ActionPlugin): pcb_txt.SetTextSize(pcbnew.wxSize(5000000, 5000000)) pcb_txt.SetLayer(pcbnew.F_SilkS) board.Add(pcb_txt) - pcb_group.AddItem(pcb_txt) + # pcb_group.AddItem(pcb_txt) + CoilPlugin().register() # Instantiate and register to Pcbnew])