Cet article fait partie de cet article. Tout d'abord, jetez un œil à ceci.
FIRST En premier.
Bien que j'aie mentionné la relation principale, il y a une raison (pas tellement) et c'est une histoire liée à Robot.java. Le fait est que Robot.java joue le rôle de Main.
C'est une partie importante.
Le plus important est de ** ne pas dysfonctionner (comportement involontaire) **.
Je pense que la prochaine chose la plus importante est ** de ne pas mettre de charge sur le robot **.
Le robot effectue un traitement en boucle. Si vous écrivez le code normalement, s'il y a une entrée, ce sera sous la forme d'une commande au moteur, etc. au moment où l'entrée est entrée, n'est-ce pas? Cependant, cette méthode pose des problèmes (parfois).
Par exemple ...
Implémentons un endroit pour faire fonctionner la suspension avec un contrôleur!
python
setSpeed(controller.getX());
Je souhaite déplacer le train de roulement automatiquement lors de la montée d'une marche. Je dois faire divers jugements parce que je déplace différentes parties et je le fais étape par étape. Ajoutez if else à setSpeed ()!
python
setSpeed(controller.getX());
(Omission)
if(controller.is_cimbMode) {
if(is_liftup){
(Omission)
if(is_advance) {
setSpeed(1);
}
}
Voici le premier mur. Si cela reste tel quel, l'entrée du moteur répétera l'entrée du contrôleur et 1 dans un court laps de temps.
Cela ne fonctionne pas bien en premier lieu Si vous le faites avec un ascenseur, cela mettra beaucoup de pression sur le robot. (Cela peut être plus facile à comprendre si vous pensez à la banque de tête) Par conséquent, même si vous essayez de vous en occuper autrement, cela devient compliqué + il devient assez difficile de comprendre comment le travail est fait. juste comme ça,,,
python
if(controller.is_climbMode) {
if(is_StopperOn && !is_liftMoving) {
setSpeed(0.3);
Timer.reset();
Timer.start();
}else if(is_liftUp && Timer.get() > 1) {
setSpeed(1);
}else {
setSpeed(0);
}
}else if(controller.hoge) {
if(fuga) {
setSpeed(-0.7);
}else {
setSpeed(0);
}
}else {
setSpeed(controller.getX());
S'il ne s'agit que du train de roulement, il sera produit en série à divers endroits ...: vague:
Ici je suis venu avec
Faisons divers jugements et confirmons la situation avant de partir ...
Quand. Selon le mentor (leader), cela s'appelle «State Bot».
・ Partie contrôleur ・ Pièce pour monter une marche ・ Partie Hoge Il peut être divisé comme ça.
C'est OK si vous décidez de la priorité du contenu à exécuter et écrivez le traitement avec une priorité élevée plus tard dans le code
Je veux qu'une classe corrige la situation, donc la classe créée est State
Cependant, il est préférable d'initialiser le champ de chaque boucle «State». En effet, une valeur qui a été manipulée une fois ne peut pas changer à moins qu'elle ne soit à nouveau manipulée. Vous pouvez le joindre avec else etc., mais pour le moment.
De plus, j'ai créé une classe appelée Const
et y ai mis les constantes.
Le mérite est ** il est facile de changer la valeur plus tard + il est facile de comprendre quelle est la valeur **
Postscript (2019/3/17): J'ai l'impression d'avoir oublié quelque chose d'important Fondamentalement, l'opération s'arrêtera lorsque vous retirerez votre main du contrôleur! Même avec le contrôle PID, assurez-vous d'arrêter lorsque le bouton n'est plus enfoncé.
En outre, la suspension est une opération de bâton, et les autres sont des opérations de bouton.
ʻEcrire dans une classe qui hérite de la classe IterativeRobot`. (L'exécution s'améliore.) Fondamentalement, il remplace la fonction de Iterative Robot. (Strictement parlant, la fonction de lsrIterativeRobotBase héritée par IterativeRobot)
Vous pouvez voir le contenu en appuyant ou en cliquant sur le triangle. (IE et Edge ne semblent pas possibles)
Un peu sur le codeur setDistancePerPulse
.
Un encodeur est une machine qui mesure la rotation d'un moteur, mais j'expliquerai cette méthode car elle est légèrement liée au programme. (Je pense qu'il y a une meilleure explication si vous recherchez sur le net)
Il y a une lumière et une partie réceptrice de lumière dans le codeur, et il y a une partition de type fente avec un espace entre elles à intervalles réguliers, et elle compte chaque fois que la partition tourne et que la lumière est bloquée. Sur la base du nombre de comptage, nous évaluerons combien le robot a bougé en multipliant la distance par rotation. La distance par rotation est déterminée en calculant ou en mesurant réellement le rapport de transmission. Il vaut mieux être posé théoriquement. Permettez-moi d'omettre la méthode ici.
Le robot lui-même n'a que des objets tels que des pilotes de moteur, Les variables d'état sont également résumées ici. La signification de chaque variable est résumée dans chaque chapitre.
variables.java
private State state;
/** Controller
*J'en ai fait une forme pour fonctionner avec deux.
*/
private XboxController driver, operator;
/** Motors
*Spark à gauche et à droite à vos pieds(Pilote de moteur)Mais,
*Talon sur l'ascenseur(C'est aussi un pilote de moteur), Sur le bras et sur la marche
*Victor SP sur les jambes pour l'escalade(Pilote de moteur)Déclaration parce qu'il y a
*
*S'il y a un pilote de moteur similaire tel que l'utilisation de deux moteurs au même endroit
*Ces pilotes de moteur peuvent être regroupés dans une classe appelée SpeedController.
*Cette fois, nous ne l'avons pas utilisé car il est physiquement résumé.
*/
private Spark driveLeft, driveRight;
private Talon liftMotor;
private VictorSP rollerMotor;
private VictorSP climbMotor;
/** Encoder, Gyro
*Un encodeur pour chacun des pieds gauche et droit et un pour l'ascenseur(Mesurer la distance parcourue
*Celui qui tombe malade)Et le gars qui a rassemblé ses pieds.
*gyro(Celui qui peut mesurer la rotation)Déclarer
*EncoderGroup est la classe d'origine
*/
private Encoder rightDriveEncoder, leftDriveEncoder;
private EncoderGroup driveEncoder;
private Encoder liftEncoder;
private ADXRS450_Gyro gyro;
/** Solenoid
*solénoïde(Ce qui déplace le cylindre à air)Déclarer
*Utilisé pour plier les bras, attraper une planche ou monter une marche
*/
private Solenoid armSolenoid, barSolenoid;
private Solenoid climbSolenoid;
/** Compressor
*compresseur(Celui qui capte l'air)Déclarer
*/
private Compressor compressor;
/** Timer for climb
*Minuterie utilisée lors de la montée d'une marche
*/
private Timer climbTimer;
/* SubModule
*Module lorsque le robot est grossièrement divisé
*Classe originale
*/
private Drive drive;
private Lift lift;
private Grabber grabber;
private Climb climb;
//Capteur pour traçage de ligne
// 0~3.La tension augmente lorsqu'il y a une ligne blanche 3V
//Malheureusement non implémenté
//private AnalogInput rightFrontSensor,
// rightBackSensor,
// leftFrontSensor,
// leftBackSensor;
/** Camera
*Celui attaché à l'ascenseur et celui attaché au cadre pour monter la marche.
*/
private CameraServer elevatorCamera, frameCamera;
/** NetWorkTable
*Pour recevoir le résultat du traitement d'image
*Ceci est également non mis en œuvre
*/
private NetworkTable networkTable;
État d'ici
<détails> Liés au lecteur </ summary>
State.java
public enum DriveState {
kManual,
kLineTrace,
kCloseToLine
} //Changement de mode: les deux derniers ne sont pas implémentés
public DriveState driveState;
public double driveStraightSpeed, driveRotateSpeed; //Valeur de contrôle du contrôleur
public double driveStraightSetpoint, driveRotateSetpoint; //Valeur cible de contrôle PID
public boolean is_drivePIDOn; //Contrôler ou non le PID
public boolean is_lineTraceOn; //S'il faut aligner la trace
public boolean is_lowInputOn; //Passer en mode de sortie faible
<détails> <détails> <détails> C'est une constante.
Il n'y a pas de temps pour énumérer (~~ copier ~~) ici comme ci-dessus, donc en japonais. À peu près divisé ·Port
** · Dimensions du champ **
** ・ Dimensions du robot **
** ・ Autres constantes ** Quatre types de. Le port est le port où le pilote du moteur, etc. est bloqué dans roboRIO (Roborio). Selon cette règle, la taille du champ est la hauteur à laquelle la balle est placée. Les dimensions du robot peuvent être Distance par impulsion de l'encodeur ou des valeurs numériques liées au robot. Les autres constantes sont zone morte et coefficient PID. Je pense que c'est plus facile à gérer si vous le divisez grossièrement. Contrôle automatique pendant les 15 premières secondes. Il fonctionne de manière entièrement automatique chaque année, mais pour une raison quelconque cette année, il est possible de contrôler le contrôleur à l'aide d'une caméra.
Ça s'appelle Sandstorm ... Nous avons utilisé une caméra pour contrôler le contrôleur. Tout le traitement est le même que Teleop, ou plutôt il appelle LAST
Finalement.
Ensuite, avant de parler du train de roulement, parlons du contrôle PID. Puis! Article précédent ⇒ FIRST
Article suivant ⇒ À propos du contrôle PID
Recommended Posts
State.java
public double liftSpeed; //Valeur de contrôle du contrôleur
public double liftSetpoint; //Valeur cible de contrôle PID
public boolean is_liftPIDOn; //Contrôler ou non le PID
State.java
public enum CargoState {
kHold,
kRelease,
kDoNothing
}
public CargoState cargoState; //Que faire du fret
public boolean is_toHoldPanel; //S'il faut tenir le panneau
public boolean is_toRetractArm; //S'il faut ranger le bras
State.java
public enum ClimbSequence {
kDoNothing("kDoNothing"),
kLiftUp("kLiftUp"),
kLocking("kLocking"),
kAdvance("kAdvance"),
kUnlocking("kUnlocking"),
kLiftDown("kLiftDown");
String name;
ClimbSequence(String name) {
this.name = name;
}
} //Pour plus de détails, voir la partie Grimper....La chaîne sert au débogage
public ClimbSequence climbSequence = ClimbSequence.kDoNothing; //État pendant la montée automatique
public boolean is_autoClimbOn; //Que vous escaladiez automatiquement
public boolean is_lockingClimb; //Que ce soit pour mettre un bouchon
public boolean is_lockedClimb; //Si le bouchon est complètement libéré
public double climbMotorSpeed; //La valeur du moteur du châssis au moment de la montée
Contenu de Const
À propos d'autonomie (à propos du contrôle pendant la tempête de sable)
teleopPeriodic ()
.