93 lines
4.1 KiB
Python
93 lines
4.1 KiB
Python
# -*- 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)) |