Vous vous rappelez les batailles de petits pois à la cantine? On a eu envie de remettre ça, mais en plus technologique et moins salissant. L'idée consiste à fabriquer une petite catapulte contrôlée par USB. Pour ça, un module Yocto-Servo, deux servos et quelques élastiques devraient faire l'affaire, le reste c'est juste de la mécanique :-)
Avec un yocto-Servo et deux petits HS-55 on peut commencer a s'amuser
Comme on ne voulait pas être obligés de fournir une alimentation externe, on a choisi des petits servos suffisamment petits pour se contenter du courant fourni par le bus USB. En l'occurrence des HS-55 de Hitec: il sont petits, pas trop chers, et disponibles n'importe où. Le problème, c'est qu'un de ces servos n'a pas la puissance pour tendre la catapulte en une fois. C'est pourquoi il a fallu imaginer un mécanisme à cliquets: le servo "pompe" pour tendre la catapulte.
La partie principale de la catapulte est le bras qui est accouplé à deux roues dentées. Il y a un cliquet par roue dentée, le premier est actionné par un des servos pour armer le bras, et deuxième sert à empêcher le bras de repartir en avant. Le deuxième servo déclenche la mise à feu en débrayant les deux cliquets
Toutes les pièces
Le mécanisme de réarmenent
Le cliqet anti-retour
C'est virtuellement prêt
Une fois le design terminé, il n'y a plus qu'à passer à la construction. On utilise du contre-plaqué peuplier de 3mm tout bête, qu'on découpe à la découpeuse laser. Les axes sont faits avec des cure-dents et des pics à brochettes. On monte le tout à la colle blanche et à la cyanolite, c'est là que le temps investi dans la modélisation 3D commence à payer: tout s'emboîte comme avec des Legos. En quelques minutes, la bête est prête.
La découpeuse laser: le rêve de tout modéliste
Bon, on a de la colle plein les doigts, mais cette fois c'est prêt IRL
Bon, il ne reste plus qu'à écrire le programme pour la contrôler. On va faire ça en Delphi. L'idée c'est de faire un objet "contrôle de catapulte" auto suffisant, qu'on pourrait ré-utiliser n'importe où. Cet objet aura deux méthodes publiques: Fire() pour tirer (si,si) et isReady() qui permettra de savoir si la catapulte est prête a tirer. On aura aussi une méthode privée Run() chargée de contrôler la séquence de tir qui sera pilotée par un timer. Pour éviter d'avoir à entrer le numéro de série du module dans le code, on a donné le nom logique "catapult" au module Yocto-Servo et on l'accède en utilisant ce nom.
private
initOk : boolean;
initError : string;
runningstate : integer ;
runTimer : TTimer;
procedure run(timer: Tobject);
public
constructor create();
procedure fire();
function isReady(var msg:string):boolean;
end;
Le constructeur de l'objet se contente d'initialiser quelques bricoles, en particulier l'API Yoctopuce.
begin
initOk := not(YISERR(yRegisterHub('usb',initError)));
runTimer := ttimer.create(nil);
runTimer.enabled := false;
runTimer.onTimer := run;
runningstate :=0;
end;
La séquence de tir consiste à débrayer les cliquets pour libérer le bras avec le servo 2, puis ensuite à effectuer quatre mouvements de va-et-vient avec le servo 1 pour réarmer la catapulte. La séquence est contrôlée par un automate à états. A chaque étape, il vérifie que le module Yocto-Servo est présent, envoie les ordres nécessaires aux servos, puis programme le timer pour déclencher l'étape suivante.
procedure ScheduleNextStep(delay:integer);
begin
runningstate := runningstate+1;
TTimer(timer).interval := delay;
TTimer(timer).enabled := true;
end;
var
FireServo,ArmingServo: TyServo;
const
FireServoLimitA = -800;
FireServoLimitB = 800;
ArmingServoLimitA = -1000;
ArmningServoLimitB = 1000;
begin
TTimer(timer).enabled:=false;
ArmingServo := yFindServo('catapult.servo1');
FireServo := yFindServo('catapult.servo2');
if not(FireServo.isOnline()) then exit;
if (runningstate=0) then exit;
case runningstate of
1 : begin
FireServo.move(FireServoLimitB,500);
ScheduleNextStep(1000);
end;
2 : begin
FireServo.move(FireServoLimitA,500);
ArmingServo.move(ArmningServoLimitB,500);
ScheduleNextStep(600);
end;
3,5,7,9 :
begin
ArmingServo.move(ArmingServoLimitA,1000);
ScheduleNextStep(1500);
end;
4,6,8,10 :
begin
ArmingServo.move(ArmningServoLimitB,500);
ScheduleNextStep(600);
end;
11 : runningstate :=0;
end;
end;
La méthode isReady() vérifie que la catapulte est prête à tirer. Cela suppose de s'assurer que l'API a été correctement initialisée, que le module Yocto-servo est connecté, et qu'il n'y a pas de séquence de tir en cours.
var
module: TyModule;
ok : boolean;
begin
ok := true;
msg := 'Catapult ready';
if not(initOk) then
begin
ok := false;
msg := initError;
end;
if (ok) then
begin
Module := yModule('catapult');
if not(Module.isOnline()) then
begin
ok := false;
msg := 'No catapult device found, check cables';
end;
end;
if (ok) and (runningstate<>0) then
begin
ok := false;
if (runningstate=1) then msg := 'Firing'
else msg := 'Rearming';
end;
isReady:=ok;
end;
La méthode Fire() se contente de vérifier que la catapulte est prête et d'initier la séquence de tir.
var
msg:string;
begin
if isReady(msg) then
begin
msg :='firing';
runningstate :=1;
run(runTimer);
end;
end;
Le reste de l'application n'est que du code d'interface Delphi, si les détails vous intérresse, le tout est disponible ici. Cette fois, c'est sûr, tout est prêt, y'à plus qu'à jouer avec.
Bon, on va pas vous mentir, il a quand même fallu quelques itérations pour arriver à un modèle qui marche bien.
Trois itérations, ça va, on a vu pire...
On se doute de ce que vous pensez juste là maintenant, vous vous dites qu'une catapulte capable de se réarmer toute seule, ça ne sert à rien si elle n'est pas aussi capable de se recharger toute seule. On est tout fait d'accord avec vous. On est en train d'y réfléchir, on vous tient au courant :-)