From 5a221478e1969df65fef919cd1c518035592f020 Mon Sep 17 00:00:00 2001 From: "@_@" Date: Wed, 29 Jul 2026 00:12:39 +0200 Subject: [PATCH] =?UTF-8?q?script=20python=20=C3=A0=20mettre=20en=20macro?= =?UTF-8?q?=20de=20FreeCad=20pour=20le=20chassis=20du=20drone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hardware/cad/py_scripts/quad_frame.py | 93 +++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 hardware/cad/py_scripts/quad_frame.py diff --git a/hardware/cad/py_scripts/quad_frame.py b/hardware/cad/py_scripts/quad_frame.py new file mode 100644 index 0000000..d45d1c8 --- /dev/null +++ b/hardware/cad/py_scripts/quad_frame.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +""" +Macro FreeCAD : génération paramétrique d'un frame de quadcopter en configuration X. + +UTILISATION : +1. Ouvrir FreeCAD +2. Menu Macro > Macros... > Créer (ou coller directement dans la console Python, View > Panels > Python console) +3. Coller ce script, l'exécuter +4. Ajuster les paramètres ci-dessous et relancer pour itérer +5. Une fois satisfait : Fichier > Exporter > STEP (.step) ou pour impression 3D : STL (.stl) + +C'est un point de départ volontairement simple (plaque + bras droits + plaque moteur). +Prochaines évolutions possibles : bras effilés, plaque du bas + standoffs, découpe pour +câblage, congés (fillets) pour la résistance aux chocs, arrondi des angles. +""" + +import FreeCAD as App +import Part +import math + +doc = App.newDocument("DroneFrame") + +# --------------------------------------------------------------------------- +# PARAMETRES (en mm) - à adapter à votre choix de moteurs / taille d'hélices +# --------------------------------------------------------------------------- +WHEELBASE = 220.0 # distance diagonale moteur-à-moteur (standard "5 pouces" ~210-230mm) +PLATE_THICKNESS = 4.0 # épaisseur de la plaque centrale et des bras (carbone typique : 3-5mm) +ARM_WIDTH = 10.0 # largeur des bras +CENTER_SIZE = 40.0 # côté de la plaque centrale carrée + +FC_MOUNT_PATTERN = 30.5 # pattern standard "mini" pour flight controller (30.5x30.5mm) +FC_HOLE_DIA = 3.2 # diamètre de perçage pour vis M3 (jeu inclus) + +MOTOR_MOUNT_PATTERN = 12.0 # ATTENTION : varie selon le moteur (12x12, 16x16, 19x16...) + # -> vérifiez la fiche technique du moteur choisi et ajustez ici +MOTOR_HOLE_DIA = 3.2 +MOTOR_PLATE_SIZE = 20.0 # taille de la plaque support moteur en bout de bras + +arm_length = WHEELBASE / 2.0 # distance centre -> axe moteur + +# --------------------------------------------------------------------------- +# Fonctions utilitaires +# --------------------------------------------------------------------------- +def make_hole(x, y, dia, height): + cyl = Part.makeCylinder(dia / 2, height) + cyl.translate(App.Vector(x, y, -1)) # dépasse un peu de chaque côté pour une coupe propre + return cyl + +# --------------------------------------------------------------------------- +# Plaque centrale +# --------------------------------------------------------------------------- +center_plate = Part.makeBox(CENTER_SIZE, CENTER_SIZE, PLATE_THICKNESS) +center_plate.translate(App.Vector(-CENTER_SIZE / 2, -CENTER_SIZE / 2, 0)) + +half_fc = FC_MOUNT_PATTERN / 2 +for sx in (-1, 1): + for sy in (-1, 1): + h = make_hole(sx * half_fc, sy * half_fc, FC_HOLE_DIA, PLATE_THICKNESS + 2) + center_plate = center_plate.cut(h) + +# --------------------------------------------------------------------------- +# Bras + plaques moteur (config X : 45°, 135°, 225°, 315°) +# --------------------------------------------------------------------------- +frame = center_plate + +for angle_deg in (45, 135, 225, 315): + # bras + arm = Part.makeBox(arm_length, ARM_WIDTH, PLATE_THICKNESS) + arm.translate(App.Vector(0, -ARM_WIDTH / 2, 0)) + arm.rotate(App.Vector(0, 0, 0), App.Vector(0, 0, 1), angle_deg) + frame = frame.fuse(arm) + + # plaque moteur en bout de bras + motor_plate = Part.makeBox(MOTOR_PLATE_SIZE, MOTOR_PLATE_SIZE, PLATE_THICKNESS) + motor_plate.translate(App.Vector(-MOTOR_PLATE_SIZE / 2, -MOTOR_PLATE_SIZE / 2, 0)) + + half_motor = MOTOR_MOUNT_PATTERN / 2 + for sx in (-1, 1): + for sy in (-1, 1): + h = make_hole(sx * half_motor, sy * half_motor, MOTOR_HOLE_DIA, PLATE_THICKNESS + 2) + motor_plate = motor_plate.cut(h) + + motor_plate.translate(App.Vector(arm_length, 0, 0)) + motor_plate.rotate(App.Vector(0, 0, 0), App.Vector(0, 0, 1), angle_deg) + frame = frame.fuse(motor_plate) + +# --------------------------------------------------------------------------- +# Affichage dans le document FreeCAD +# --------------------------------------------------------------------------- +Part.show(frame, "DroneFrame") +doc.recompute() + +print("Frame généré : wheelbase = %.1fmm, épaisseur = %.1fmm" % (WHEELBASE, PLATE_THICKNESS)) \ No newline at end of file