Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: Base/Base.cpp
- Revision:
- 0:1cfd66c3a181
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Base/Base.cpp Wed May 22 16:54:27 2019 +0000 @@ -0,0 +1,142 @@ +#include "Base.h" + +// Constructeur: +Base::Base(Moteur* moteurG, Moteur* moteurD, Odometrie* odometrie, int update_delay_us): + m_asservissement_distance(1, 1, 1), m_asservissement_orientation(1, 1, 1) { + + m_moteurG = moteurG; + m_moteurD = moteurD; + m_moteurs_isEnabled = false; + + // Odométrie: + m_odometrie = odometrie; + + // Asservissement: + m_pos_distance = 0; + m_pos_orientation = 0; + m_moteurG->setPWM_max(0.4); + m_moteurD->setPWM_max(0.4); + m_moteurG->setOffset(0.1); + m_moteurD->setOffset(0.1); + m_pwm_dynamic = 0.2f; // max = 0.6 - 0.1 + + // Erreur maximale: + m_max_erreur_distance = 300; + m_max_erreur_orientation = 3; + + // Répartition PWM entre distance et orientation: + m_distance_orientation_ratio = 0.5f; // 50% -> distance, 50% -> orientation + + // Mesure du déplacement toutes les <update_delay_us> µs: + m_ticker.attach_us(callback(this, &Base::update), update_delay_us); // 2 kHz pour 500 us +} + +// Setters: +void Base::setDistanceTo(float d) { m_asservissement_distance.toValue(d); } +void Base::setOrientationTo(float o) { m_asservissement_orientation.toValue(M_PI * o / 180.0f ); } + +void Base::setPID_distance(float P, float I, float D) { + m_asservissement_distance.setPID(P, I, D); +} +void Base::setPID_orientation(float P, float I, float D) { + m_asservissement_orientation.setPID(P, I, D); +} + +// Getters: +float* Base::getErreur_distance_ptr() { return &m_erreur_distance; } +float* Base::getErreur_orientation_ptr() { return &m_erreur_orientation; } +float* Base::getPID_PWM_distance_ptr() { return &m_pwm_distance; } +float* Base::getPID_PWM_orientation_ptr() { return &m_pwm_orientation; } +float* Base::getPID_PWM_gauche_ptr() { return &m_pwm_gauche; } +float* Base::getPID_PWM_droite_ptr() { return &m_pwm_droite; } + +/*** Déplacement ***/ + +// Start: +void Base::start() { + m_moteurs_isEnabled = true; +} + +void Base::stop() { + m_moteurs_isEnabled = false; + + // Arrêt des moteurs: + m_moteurG->stop(); + m_moteurD->stop(); +} + + +// Stop: + +// Avant: (en mm) +void Base::forward(float d) { + m_pos_distance += d; + setDistanceTo(m_pos_distance); +} + +// Arrière: (en mm) +void Base::backward(float d) { + m_pos_distance -= d; + setDistanceTo(m_pos_distance); +} + +// Tourner: (en °) +void Base::turn(float o) { + m_pos_orientation += o; + setOrientationTo(m_pos_orientation); +} + +// Renvoie le signe de la valeur: +template <typename T> int sign(T val) { + return (T(0) < val) - (val < T(0)); +} + + +// Mise à jour de l'odometrie et de l'asservissement: +void Base::update() { + // Mise à jour de la position: + m_odometrie->update(); + + // Calcul de l'erreur de distance: + float distance = m_odometrie->getRealDistance(); + float erreur_distance = m_asservissement_distance.computeError(distance); + + // Calcul de l'erreur d'orientation: + float theta = m_odometrie->getTheta(); + float erreur_theta = m_asservissement_orientation.computeError(theta); + + // Correction de l'erreur: + if(abs(erreur_distance) > m_max_erreur_distance) erreur_distance = m_max_erreur_distance * sign(erreur_distance); + if(abs(erreur_theta) > m_max_erreur_orientation) erreur_theta = m_max_erreur_orientation * sign(erreur_theta); + + // PWM correspondant à la distance et à l'orientation: + float pwm_distance = (erreur_distance / m_max_erreur_distance) * m_distance_orientation_ratio; + float pwm_theta = (erreur_theta / m_max_erreur_orientation) * (1.0f - m_distance_orientation_ratio); + + // PWM à envoyer aux moteurs: + float pwm_droite = (pwm_distance + pwm_theta) * m_pwm_dynamic; + float pwm_gauche = (pwm_distance - pwm_theta) * m_pwm_dynamic; + + // Commande des moteurs: + if (m_moteurs_isEnabled == true) { + m_moteurD->turn(pwm_droite); + m_moteurG->turn(pwm_gauche); + } + + // Sauvegarde / Debug: + m_pwm_distance = pwm_distance; + m_pwm_orientation = pwm_theta; + m_erreur_distance = erreur_distance; + m_erreur_orientation = erreur_theta; + m_pwm_droite = pwm_droite; + m_pwm_gauche = pwm_gauche; +} + +// Getters: +float Base::getErreurDistance() { return m_erreur_distance; } +float Base::getErreurOrientation() { return m_erreur_orientation; } + +//float Base::moveTo(float X, float Y); +//float Base::setAngle(); + +//float Base::turn(float angle); \ No newline at end of file