mercredi 25 mai 2016

Premiers tours de roues

Juste pour faire bouger la mécanique, Pablo réalise ses premiers pas. A ce stade il reste un simple véhicule télécommandé par joystick.


Préparation d'une mission

En premier je sélectionne la forme qui sera tracée sur le sable. j'ai choisi le format DXF car il est vectoriel et il est très répandu. On trouve un peu partout des fichiers qui représentent tout un tas de formes à tracer en deux dimensions.
J'utilise ensuite une application développée en C# pour transformer les vecteurs en coordonnées GPS.
D'abord on choisi un emplacement sur la carte.
 

Il suffit de choisir l'échelle, l'orientation et simplement cliquer.



On peut vérifier les coordonnées en exportant un fichier KML dans google map. Pablo utilise un autre fichier avec les mêmes coordonnées mais avec plus d'information comme par exemple lever et baisser un outil pour dessiner sur le sable.

8,4450406781251    -2,08504594716869    False
48,4450461265302    -2,08506101814332    True
48,4450517909435    -2,08506631507817    True
48,4450666555887    -2,08506418650572    True
48,4451036193834    -2,08505440264829    True
48,4451291246728    -2,08504492712652    True
48,4451318136836    -2,08504202502935    True
48,445129096546    -2,08503937794103    True
48,4451265609555    -2,08503508080721    True
48,4451263169431    -2,08502652944985    True
48,4451327151583    -2,08499652761686    True
48,445136988763    -2,08497625580294    True
48,4451367353441    -2,08497106468962    True
48,4451348424797    -2,08496974890767    True
48,4451308889332    -2,08497403059451    True
48,4451267488849    -2,08498364311531    True
...


mardi 29 mars 2016

Commande de moteurs

La carte SaberTooth 2 x 32 est un bon choix pour contrôler pablo car la commande des deux moteurs peut se faire à l'aide du port USB. 

Description
  • Contrôleur de moteur régénératif à double canal
  • Courant : 32 A en continu, 64 A en crête par canal
  • Fréquence de commutation ultrasonique de 30 kHz
  • Modes d'entrée USB, série, R/C et analogique
  • Dimensions : 6,99 x 7,34 x 2,54 cm
  • Poids : 125 g

Le Contrôleur de Moteur Sabertooth 2x32 A de Dimension Engineering est un contrôleur de moteur à double canal capable d'alimenter deux moteurs en 32 ampères, avec jusqu'à 64 ampères de courant de crête par moteur. Il peut être géré depuis une entrée radiocommandée, analogique, série TTL ou USB. Il utilise un contrôleur et le freinage régénératif pour un fonctionnement efficace. Sabertooth 2x32 dispose aussi d'entrées de signal et de sorties de puissance supplémentaires, ainsi que d'options de configuration améliorées.

 

Commande        Description
M1              Motor 1
M2              Motor 2
MD              Drive channel. 

                Both motors.
                Forward/Backwards in Mixed Mode
MT              Turn channel. 

                Both motors. 
                Right/Left in Mixed Mode
P1              Power output 1
P2              Power output 2
R1              Ramp rate motor 1
R2              Ramp rate motor 2
Q1              Auxiliary variable 1
Q2              Auxiliary variable 2


M1:get
M2:get
Returns the duty cycle of the M1 or M2 output, from -2047 for full reverse to 2047 for full forward. 

P1:get
P2:get
Returns the duty cycle of the P1 output. -2047 is no output, and 2047 is full power.

S1:get
S2:get
Returns the input value for the S1 or S2 inputs.

A1:get
A2:get
Returns the input value for the S1 or S2 inputs. By default these are analog in USB and serial modes. 

M1:getb
M2:getb
Returns the battery voltage in tenths of a volt. A battery reading of 12.5 volts will report as B125

M1:getc
M2:getc
Returns the motor current in tenths of an amp.

M1:gett
M2:gett
Returns the temperature of the output transistors for this channel, in degrees C. 

M1:shutdown
M2:shutdown
Shuts off the motor output. Using the shutdown command will put the motor in a hard brake state.

M1:startup
M2:startup
Returns the motor channel from a shutdown state to normal operation.  

 

mardi 22 mars 2016

Software

C#  , what else ... 

Il faudra gérer
  • Le contrôleur des moteurs Saberthooth qui assurent la propulsion
  • Les capteurs odomètres qui mesurent la distance parcourue
  • Le GPS pour se géolocaliser
  • La boussole pour garder le cap
  • La caméra pour éviter les obstacles 

mercredi 16 mars 2016

Batterie : présentation

Voici les caractéristique de la batterie embarquée sur PABLO :

Type     Sonnenschein GF 12 033 Y G1
Nominal voltage 12 V
Nominal capacity C5 (30 °C) 32.5 Ah
Nominal capacity C20 (30 °C) 38.0 Ah
Length (l) max. 210 mm
Width (b/w) max. 175 mm
Height (h) max. 175 mm
Weight 14.6 kg



Avantages des batteries Gel

Les batteries gel sont des batteries étanches : pas d'entretien, pas d'ajout d'eau distillée. Sécurité renforcée par rapport aux batteries plomb ouvert. Les batteries « gel » sont bien adaptées pour les décharges profondes. Une batterie gel peut supporter la décharge à 100 % et retrouve sa capacité nominale si le temps de maintien déchargé est court.

Inconvénients des batteries Gel

La résistance interne de ce type de batterie est relativement élevée et elles ne supportent donc pas des vitesses de charge et de décharge élevées. En continu, le courant de charge ne doit pas excéder C/10. Les batteries gel sont donc rechargées relativement lentement.

Châsis : présentation

Côté châssis, le squelette de PABLO est constitué de profilé en aluminium de 2cm de section. L'assemblage est facilité par des équerres. On reconnait les deux moteurs de chaque côté et l'emplacement pour la batterie au centre. L'électronique viendra par la suite sur le dessus de la structure.







lundi 14 mars 2016

Odométrie : programme Arduino Micro

Pour compter et décompter le nombre de tours, on utilise un Arduino micro.

Le programme se présente sous quelques ligne en language C qui permettent de remonter les compteurs vers un port série virtuel.

int MOTG_INT = 2; // interrupt sur digital 0 = INT 2
int MOTG_PHA = 0; //  input digital 0
int MOTG_PHB = 1; //  input digital 1
int MOTG_VALA ;
int MOTG_VALA_old ;
int MOTG_VALB ;
volatile int MOTG_COUNT;
int MOTG_COUNT_OLD;

int MOTD_INT = 1; // interrupt sur digital 3 = INT 1
int MOTD_PHA = 3; //  input digital 3
int MOTD_PHB = 2; //  input digital 2
int MOTD_VALA ;
int MOTD_VALA_old ;
int MOTD_VALB ;
volatile int MOTD_COUNT;
int MOTD_COUNT_OLD;

String inputString = "";      // La chaine de commande reçue
char inChar;                  //  1 caractère reçu
boolean commande_ok = false;  //
boolean _odo_run = false;


void setup() {
  attachInterrupt(MOTG_INT, interrupt_MotG_phA, RISING );
  pinMode(MOTG_PHA, INPUT);
  pinMode(MOTG_PHB, INPUT);

  attachInterrupt(MOTD_INT, interrupt_MotD_phA, RISING );
  pinMode(MOTD_PHA, INPUT);
  pinMode(MOTD_PHB, INPUT); 
}

void interrupt_MotG_phA()
{
  if (!_odo_run) return;
 
  MOTG_VALA = digitalRead(MOTG_PHA);
  MOTG_VALB = digitalRead(MOTG_PHB);

  if ( MOTG_VALA != MOTG_VALA_old)
  {
    //  modification du signal sur l'entrée MOTG_PHA
  if (MOTG_VALA==1)
    {
      // signal sur l'entrée MOTG_PHA = 1
      if (MOTG_VALB==0)
        {
          MOTG_COUNT++;
        }
      else
        {
          MOTG_COUNT--;
        }
    }
    else
    {
      // signal sur l'entrée MOTG_PHA = 0
      if (MOTG_VALB==0)
        {
          MOTG_COUNT--;
        }
      else
        {
          MOTG_COUNT++;
        }     
    
    }
    MOTG_VALA_old = MOTG_VALA;
  }
  delay(1);
}

void interrupt_MotD_phA()
{
   if (!_odo_run) return;
 
  MOTD_VALA = digitalRead(MOTD_PHA);
  MOTD_VALB = digitalRead(MOTD_PHB);

  if ( MOTD_VALA != MOTD_VALA_old)
  {
    //  modification du signal sur l'entrée MOTD_PHA
  if (MOTD_VALA==1)
    {
      // signal sur l'entrée MOTD_PHA = 1
      if (MOTD_VALB==0)
        {
          MOTD_COUNT++;
        }
      else
        {
          MOTD_COUNT--;
        }
    }
    else
    {
      // signal sur l'entrée MOTD_PHA = 0
      if (MOTD_VALB==0)
        {
          MOTD_COUNT--;
        }
      else
        {
          MOTD_COUNT++;
        }     
    
    }
    MOTD_VALA_old = MOTD_VALA;
  }
  delay(1);
}

void loop()
{
  if (Serial.available() > 0)
  {
 // lecture du caractère reçu
    inChar = (char)Serial.read();
   
    if (inChar == 13)
    {
      //  Retour chariot = commande complète

          if (inputString == "ODO_start")
          {
            //  La commande est reconnue
                commande_ok = true ;
            //  accusé reception
                Serial.print(inputString);
                Serial.println(" OK");

                _odo_run = true;

          }     

          if (inputString == "ODO_reset")
          {
            //  La commande est reconnue
                commande_ok = true ;
            //  accusé reception
                Serial.print(inputString);
                Serial.println(" OK");

                MOTG_COUNT = 0;
                MOTG_COUNT_OLD = 0;
                MOTD_COUNT = 0;
                MOTD_COUNT_OLD = 0;
          }     

          if (inputString == "ODO_stop")
          {
            //  La commande est reconnue
                commande_ok = true ;
                    
            //  accusé reception
               Serial.print(inputString);
               Serial.println(" OK");

               _odo_run = false;
           }     




      //  Si la commande n'est pas reconnue
          if (commande_ok != true)
          {
              Serial.print(inputString);
              Serial.println(" KO");
          }

      //  prêt à recevoir une nouvelle commande
          commande_ok = false;
     
      //  Vidange de la chaine de commande
          inputString = "" ;
    }
    else
    {
      // ajoute le caractère
        inputString += inChar;   
    }
  }

 
  if((MOTG_COUNT_OLD!=MOTG_COUNT) || (MOTD_COUNT_OLD!=MOTD_COUNT))
  {
    Serial.print(MOTG_COUNT, DEC);
    Serial.print(" ");
    Serial.print(MOTD_COUNT, DEC);
    Serial.println();
    if(MOTG_COUNT_OLD!=MOTG_COUNT) MOTG_COUNT_OLD=MOTG_COUNT;
    if(MOTD_COUNT_OLD!=MOTD_COUNT) MOTD_COUNT_OLD=MOTD_COUNT;
  }
  delay(20);
}
La remontée des compteurs sur le Port COM4 (9600bauds, 8 bits, 1 stop)