Lorenzo Dunau / dribble

Files at this revision

API Documentation at this revision

Comitter:
lorenzodunau
Date:
Fri May 13 06:26:53 2022 +0000
Parent:
30:4e7cf52ac2dd
Commit message:
bibliotheque pour commander le dribble;

Changed in this revision

DRIBBLE.cpp Show annotated file Show diff for this revision Revisions of this file
DRIBBLE.h Show annotated file Show diff for this revision Revisions of this file
MX12.cpp Show diff for this revision Revisions of this file
MX12.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DRIBBLE.cpp	Fri May 13 06:26:53 2022 +0000
@@ -0,0 +1,34 @@
+/**
+ * @file MX12.ccp
+ * @brief This file contains all the methods of the MX12 class
+ *        whose prototypes are in the MX12.h header file
+ */
+
+#include "DRIBBLE.h"
+#include "math.h"
+
+dribbleur::dribbleur(PinName tx)
+    : _moteurDribble(tx)    // initializes UnbufferedSerial object
+{
+    _moteurDribble.pulsewidth_us(0);
+    _moteurDribble.period_us(100);
+};
+
+void dribbleur::SetSpeed(int pourcentage)
+{
+    _moteurDribble.pulsewidth_us(pourcentage);
+};
+
+void dribbleur::test()
+{
+    SetSpeed(10);
+};
+
+void dribbleur::SetSpeedSmooth()
+{
+    int i;
+    for (i=0;i<=30;i=i+1){
+        SetSpeed(i);
+        thread_sleep_for(100);
+        };
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DRIBBLE.h	Fri May 13 06:26:53 2022 +0000
@@ -0,0 +1,31 @@
+/**  
+ * @file MX12.h
+ * @brief this header file contains all required definitions and 
+ *        basic utilities functions to manage au bus of servomotor 
+ *        Dynaminel MX12
+ */ 
+#ifndef MBED_DRIBBLE_H_
+#define MBED_DRIBBLE_H_
+
+#include "mbed.h"
+class dribbleur
+{
+public:
+    dribbleur(PinName tx = D15);
+
+    void SetSpeed(int pourcentage);
+    // Permet de choisir une fraction de la vitesse maximal du dribbleur 
+    
+    void test();
+    // permet de vérifier que le bribbleur est opérationnel
+
+    void SetSpeedSmooth();
+    // permet d'atteindre la vitesse de croisière de manière smooth
+
+    void eteindre_moteurs();
+    // permet d'enlever le couple dans les moteurs
+
+protected:
+    PwmOut _moteurDribble;
+};
+#endif
\ No newline at end of file
--- a/MX12.cpp	Fri Feb 04 09:22:50 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,527 +0,0 @@
-/**
- * @file MX12.ccp
- * @brief This file contains all the methods of the MX12 class
- *        whose prototypes are in the MX12.h header file
- */
-
-#include "MX12.h"
-#include "math.h"
-
-MX12::MX12(PinName tx, PinName rx, int baud)
-    : _mx12(tx, rx)    // initializes UnbufferedSerial object
-{
-    /*  Serial bus setup
-     */
-    // // Set desired properties (baud-8-N-1)
-    _mx12.baud(baud);     /* modulation speed */
-    _mx12.format(
-        8,                /* bits */
-        SerialBase::None, /* parity */
-        1                 /* stop bit */
-    );
-    // Register a callback to process a Rx (receive) interrupt.
-    _mx12.attach(callback(this, &MX12::_Rx_interrupt), SerialBase::RxIrq);
-
-    // variable used for message reception
-    _status_pck = {.raw = "",
-                   .n_byte = 0,
-                   .servo_id = 0,
-                   .length = 0,
-                   .error = 0,
-                   .n_param = 0,
-                   .param = "",
-                   .received_checksum = 0,
-                   .calculated_checksum = 0,
-                   .parsed = false,
-                   .valid = false
-                  };
-
-    _parser_state = {.expected_field = PacketField::Header1,
-                     .byte_index = 0,
-                     .param_index = 0
-                    };
-
-    // Internal defaults states
-    _bus_state = SerialState::Idle;
-
-}
-
-void MX12::SetSpeed(unsigned char mot_id, float speed)
-{
-    char data[2];
-
-    // Speed absolute value
-    int goal = (0x3ff * abs(speed));
-
-    // Spin direction (CW is negative)
-    if (speed < 0) {
-        goal |= (0x1 << 10);
-    }
-
-    data[0] = goal & 0xff;
-    data[1] = goal >> 8;
-
-    // Send instruction
-    _bus_state = SerialState::Writing;
-    rw(mot_id, CONTROL_TABLE_MOVING_SPEED, 2, data);
-}
-
-void MX12::SetSpeed_rad_s(unsigned char mot_id, float speed)
-{
-    if (speed > MX12_ABSOLUTE_MAX_SPEED_RAD_S) {
-        SetSpeed(mot_id, 1);
-    } else if (speed < -MX12_ABSOLUTE_MAX_SPEED_RAD_S) {
-        SetSpeed(mot_id, -1);
-    } else {
-        SetSpeed(mot_id, speed / MX12_ABSOLUTE_MAX_SPEED_RAD_S);
-    }
-}
-
-char MX12::IsAvailable(void)
-{
-    return (_bus_state == SerialState::Idle);
-}
-
-void MX12::rw(unsigned char mot_id, char address, char len, char *data)
-{
-
-    /* Set variables for reception from servovotor */
-    _answer  = 0;
-    _status_pck = {.raw = "",
-                   .n_byte = 0,
-                   .servo_id = 0,
-                   .length = 0,
-                   .error = 0,
-                   .n_param = 0,
-                   .param = "",
-                   .received_checksum = 0,
-                   .calculated_checksum = 0,
-                   .parsed = false,
-                   .valid = false
-                  };
-    _parser_state = {.expected_field = PacketField::Header1,
-                     .byte_index = 0,
-                     .param_index = 0
-                    };
-
-
-    /* Initialise instruction packet to forge.
-     * Instruction Packet is the command data sent to the servomotor.
-     *
-     * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum|
-     * |-------|-------|---------|------|-----------|---------------|--------|
-     * |  0xFF |  0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM |
-     * | cmd[0]| cmd[1]|  cmd[2] |cmd[3]|  cmd[4]   |cmd[5]...      |        |
-     *                  \__  ___/                    \_  _/ \__  __/
-     *                     \/           |              \/      \/            |
-     *                   mot_id         |           address   data           |
-     *                                  |                     (len = N-1)    |
-     *                                  \__________________  ________________/
-     *                                                     \/
-     *                                                  Length ( cmd[3] )
-     */
-    char packet[16];
-    unsigned char packet_length;
-
-    /* Initialise checksum to calculate
-     * It is used to check if packet is damaged during communication.
-     * Status Checksum is calculated according to the following formula:
-     *
-     * Status Checksum = ~( ID + Length + Error + Parameter1 + … Parameter N )
-     */
-    char checksum = 0x00;
-
-    /* header 1 = 0xFF (dynamixel protocol 1.0) */
-    packet[0] = 0xff;
-
-    /* header 2 = 0xFF (dynamixel protocol 1.0) */
-    packet[1] = 0xff;
-
-    /* packet ID i.e. servomotor id (dynamixel protocol 1.0) */
-    packet[2] = mot_id;
-    checksum += packet[2];
-
-    /* Guess instruction type. NULL for read, not NULL for write */
-    if(data == NULL) { // read instruction
-        /* byte length of the instruction: parameter and checksum field.   */
-        /* for read instruction:   1 INSTR +                               */
-        /*       2 PARAM (starting address, length of data) + 1 CHKSUM     */
-        packet[3] = 4;
-        checksum += packet[3];
-
-        /* set write instruction */
-        packet[4] = PROTOCOL_INSTRUCTION_READ;
-        checksum += packet[4];
-
-        /* Param 1: address to read in the Control Table of RAM Area */
-        packet[5] = address;
-        checksum += packet[5];
-
-        /* Param 2: number of bytes to read in the Control Table of RAM Area */
-        packet[6] = len;
-        checksum += packet[6];
-
-        /* Checksum = ~( ID + Length + Instruction + Param1 + … Param N ) */
-        packet[7] = ~checksum;
-
-        packet_length = 8;
-    } else { // write instruction
-        /* byte length of the instruction: parameter and checksum field     */
-        /* For write instruction:   1 INSTR +                               */
-        /*       (1+len)PARAM (starting Address, bytes to write) + 1 CHKSUM */
-        packet[3] = 3 + len;
-        checksum += packet[3];
-
-        /* set read instruction */
-        packet[4] = PROTOCOL_INSTRUCTION_WRITE;
-        checksum += packet[4];
-
-        /* Param 1: address to write in the "Control Table of RAM Area" */
-        packet[5] = address;
-        checksum += packet[5];
-
-        /* Param 2 to N: data to write in the Control Table of RAM Area */
-        for(char i = 0; i < len; i++) {
-            packet[6 + i] = data[i];
-            checksum += data[i];
-        }
-
-        /* Checksum = ~( ID + Length + Instruction + Param1 + … Param N ) */
-        packet[6 + len] = ~checksum;
-
-        packet_length = 7 + len;
-    }
-
-    // Send packet
-    if(mot_id != 0xFE) {
-        for(char i = 0; i < packet_length; i++) {
-            _mx12.write(&packet[i], 1);
-        }
-    }
-}
-
-// Debug function to print Serial read
-void MX12::PrintSerial()
-{
-    for(int i = 0; i < _status_pck.n_byte; i++) {
-        printf("%x ", _status_pck.raw[i]);
-    }
-    printf("\n");
-}
-
-char MX12::ReadSerial()
-{
-    char data;
-    for(int i = 0; i < _status_pck.n_byte; i++) {
-    }
-    return data;
-}
-
-MX12::Status MX12::GetStatus()
-{
-    // Return the corresponding status code
-    switch(_status_pck.error) {
-        case 0:
-            return Ok;
-            break;
-        case 1 << 0:
-            return InputVoltageError;
-            break;
-        case 1 << 1:
-            return AngleLimitError;
-            break;
-        case 1 << 2:
-            return OverheatingError;
-            break;
-        case 1 << 3:
-            return RangeError;
-            break;
-        case 1 << 4:
-            return ChecksumError;
-            break;
-        case 1 << 5:
-            return OverloadError;
-            break;
-        case 1 << 6:
-            return InstructionError;
-            break;
-        default:
-            return Unknown;
-    }
-}
-
-void MX12::_Rx_interrupt()
-{
-
-    char c;
-
-    // Try to read serial
-    if(_mx12.read(&c, 1)) {
-
-        _status_pck.raw[(_parser_state.byte_index)++] = c;
-
-        // State-machine parsing
-        switch(_parser_state.expected_field) {
-
-            /* c char is interpreted as a Header1 field */
-            case PacketField::Header1:
-
-                /* do nothing and set next state to Header2 */
-                _parser_state.expected_field = PacketField::Header2;
-                break;
-
-            /* c char is interpreted as a Header2 field */
-            case PacketField::Header2:
-
-                /* do nothing and set next state to Id */
-                _parser_state.expected_field = PacketField::Id;
-                break;
-
-            /* c char is interpreted as ID field */
-            case PacketField::Id:
-
-                /* store ID, update checksum and set next state to Length */
-                _status_pck.servo_id = c;
-                _status_pck.calculated_checksum += c;
-                _parser_state.expected_field = PacketField::Length;
-                break;
-
-            /* c char is interpreted as length of message data field
-             * Length = number of Parameters + 2
-             * where 2 stands for Length field (1 byte) + Error filed (1 byte)
-             */
-            case PacketField::Length:
-
-                /* store number of param into _status_pck.n_param,
-                 * update calculated_checksum and set next state to Error
-                 */
-                _status_pck.n_param = c - 2;
-                _status_pck.calculated_checksum += c;
-                _parser_state.expected_field = PacketField::Error;
-                break;
-
-            /* c char is interpreted as error status field */
-            case PacketField::Error:
-
-                /* store error status, update checksum
-                 * and set next state to Data
-                 */
-                _status_pck.error = c;
-                _status_pck.calculated_checksum += c;
-                _parser_state.expected_field = PacketField::Data;
-                break;
-
-            /* c char is interpreted as a param field */
-            case PacketField::Data:
-
-                /* store current param, increase param_index
-                 * and update checksum */
-                _status_pck.param[(_parser_state.param_index)++] = c;
-                _status_pck.received_checksum += c;
-
-                /* increase param index (_parser_state.dataCount)
-                 * and test if it is the last param to read
-                 */
-                if(_parser_state.param_index > _status_pck.n_param) {
-                    /* reset param index and set next state to Checksum */
-                    _parser_state.param_index = 0;
-                    _parser_state.expected_field = PacketField::Checksum;
-                }
-                break;
-
-            /* c char is interpreted as Checksum field */
-            case PacketField::Checksum:
-
-                /* store received_checksum, set parsed, store n_byte,
-                 * evalutate valid and set next state to Header1 */
-                _status_pck.received_checksum = c;
-                _status_pck.parsed = true;
-                _status_pck.n_byte = _parser_state.byte_index;
-                _status_pck.valid = (_status_pck.received_checksum == c);
-                _parser_state.expected_field = PacketField::Header1;
-
-                /* set seriel state to Idle */
-                _bus_state = SerialState::Idle;
-                break;
-
-            default:
-
-                /* unexpected case. If it occurs it would be due to a
-                 * code error of this class  */
-                break;
-        }
-    }
-}
-
-/* Code from previous version of the class */
-
-/*
-void MX12::ReadPosition(unsigned char mot_id) {
-    // Make a request, interrupt takes care of everything else
-    _state = State::ReadingPosition;
-    rw(mot_id, 0x24, 2, NULL);
-}
-
-float MX12::GetPosition(unsigned char mot_id) {
-    return _angle[mot_id];
-}
-*/
-
-
-
-
-
-
-void MX12::cmd_moteur(float Vavance, float Vlat, float Wz)
-{
-    // mettre en mode wh
-    char data[2];
-    data[1] = 0;
-    data[0] = 0;
-    _bus_state = SerialState::Writing;
-    rw(1, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-    rw(2, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-    rw(3, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-
-
-    _bus_state = SerialState::Writing;
-    rw(1, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-    rw(2, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-    rw(3, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-
-    float W1;
-    float W2;
-    float W3;
-    float Rc;
-    float R;
-    float x1;
-    float x2;
-    float x3;
-    float y1;
-    float y2;
-    float y3;
-    float a1;
-    float a2;
-    float a3;
-    Rc=0.08;  // rayon du chassis*10
-    R=0.019;  // rayon de la roue*10
-    W1=0;
-    W2=0;
-    W3=0;
-    a1 = 4.74 ;
-    a2 = 0.5;
-    a3 = 2.64;
-    x1 = -0.0024;
-    x2 = 0.0625;
-    x3 = -0.0643;
-    y1 = -0.073;
-    y2 = 0.0361;
-    y3 = 0.037;
-    //Vtm_smax=0.8; //sert pour calculer valeurs -999->999
-    //Vnm_smax=0.9;
-    //Wcrd_smax=2.9;
-    //if (Vtm_s>Vtm_smax)
-    // {Vtm_s=Vtm_smax;}
-    //if (Vnm_s>Vnm_smax)
-    //  {Vnm_s=Vnm_smax;}
-    //if (Wcrd_s>Wcrd_smax)
-    //  {Wcrd_s=Wcrd_smax;}
-    //if (Wcrd_s<-Wcrd_smax)
-    //  {Wcrd_s=-Wcrd_smax;}
-
-    W1=1/R*(-cosf(a1)*Vavance + sinf(a1)*y1*Wz - sinf(a1)*Vlat + cosf(a1)*x1*Wz); //loi de commande moteur 1
-    W2=1/R*(-cosf(a2)*Vavance + sinf(a2)*y2*Wz - sinf(a2)*Vlat + cosf(a2)*x2*Wz);
-    W3=1/R*(-cosf(a3)*Vavance + sinf(a3)*y3*Wz - sinf(a3)*Vlat + cosf(a3)*x3*Wz);
-    printf("%d %d %dn\r",(int)(1000*W1),(int)(1000*W2),(int)(1000*W3));
-
-
-    SetSpeed_rad_s(1,W1);  // impose la vitesse au moteur 1
-    SetSpeed_rad_s(2,W2);
-    SetSpeed_rad_s(3,W3);
-
-
-
-}
-
-void MX12::cmd_moteur_rampe_unitaire(int id_moteur, float w_moteur, int step, float time)
-{
-
-}
-
-void MX12::eteindre_moteurs()
-{
-    char data[1];
-
-    data[0] = 0;
-
-
-    // Send instruction
-    _bus_state = SerialState::Writing;
-    rw(1, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
-    _bus_state = SerialState::Writing;
-    rw(2, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
-    _bus_state = SerialState::Writing;
-    rw(3, CONTROL_TABLE_TORQUE_ENABLE, 1, data);
-}
-
-
-
-void MX12::cmd_moteur_multiturn(float pos1, float pos2, float pos3)
-{
-    // eteindre les moteurs
-    eteindre_moteurs();
-    // mettre en mode multiturn
-    char data[2];
-    data[1] = 255;
-    data[0] = 15;
-    _bus_state = SerialState::Writing;
-    rw(1, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-    rw(2, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-    rw(3, CONTROL_TABLE_CW_ANGLE_LIMIT, 2, data);
-
-
-    _bus_state = SerialState::Writing;
-    rw(1, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-    rw(2, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-    rw(3, CONTROL_TABLE_CCW_ANGLE_LIMIT, 2, data);
-
-    //relever la position
-    int pas1 = pos1-28672/60;
-    int pas2 = pos2-28672/60;
-    int pas3 = pos3-28672/60;
-
-    for (int i = 0; i < 61; i++) {
-        int goal_position1 = i * pas1 - 28672;
-        if (goal_position1 < 0) {
-            goal_position1 = goal_position1 + 28627 + 36864;
-        }
-        char data1[2];
-        data1[1] = goal_position1%256;
-        data1[0] = goal_position1/256;
-
-        int goal_position2 = i * pas2 - 28672;
-        if (goal_position2 < 0) {
-            goal_position2 = goal_position2 + 28627 + 36864;
-        }
-        char data2[2];
-        data2[1] = goal_position2%256;
-        data2[0] = goal_position2/256;
-
-        int goal_position3 = i * pas3 - 28672;
-        if (goal_position3 < 0) {
-            goal_position3 = goal_position3 + 28627 + 36864;
-        }
-        char data3[2];
-        data3[1] = goal_position3%256;
-        data3[0] = goal_position3/256;
-
-        rw(1, CONTROL_TABLE_GOAL_POSITION, 2, data1);
-        thread_sleep_for(60);
-        rw(2, CONTROL_TABLE_GOAL_POSITION, 2, data2);
-        thread_sleep_for(60);
-        rw(3, CONTROL_TABLE_GOAL_POSITION, 2, data3);
-        thread_sleep_for(60);
-
-        thread_sleep_for(1000);
-    }
-}
--- a/MX12.h	Fri Feb 04 09:22:50 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-/**  
- * @file MX12.h
- * @brief this header file contains all required definitions and 
- *        basic utilities functions to manage au bus of servomotor 
- *        Dynaminel MX12
- */ 
-#ifndef MBED_MX12_H_
-#define MBED_MX12_H_
-
-#include "mbed.h"
-
-#define MX12_PACKET_MAX_SIZE 32
-#define MX12_MAX_MOTOR_COUNT 16
-
-#define MX12_SPEED_QUANTA_RPM 0.916 /* Data from MX12 e-manual */
-#define MX12_ABSOLUTE_MAX_SPEED_RAD_S 98.13
-
-
-
-/* Dynamixel protocol v1.0 : Instructions
- ******************************************/
-#define PROTOCOL_INSTRUCTION_PING          0x01
-#define PROTOCOL_INSTRUCTION_READ          0x02
-#define PROTOCOL_INSTRUCTION_WRITE         0x03
-#define PROTOCOL_INSTRUCTION_REG_WRITE     0x04
-#define PROTOCOL_INSTRUCTION_ACTION        0x05
-#define PROTOCOL_INSTRUCTION_FACTORY_RESET 0x06
-#define PROTOCOL_INSTRUCTION_REBOOT        0x08
-#define PROTOCOL_INSTRUCTION_SYNC_WRITE    0x83
-#define PROTOCOL_INSTRUCTION_BULK_READ     0x92
-
-/* Dynamixel protocol v1.0 : Contro table content
- ************************************************/
-#define CONTROL_TABLE_MODEL_NUMBER            0
-#define CONTROL_TABLE_FIRMWARE_VERSION        2 
-#define CONTROL_TABLE_ID                      3
-#define CONTROL_TABLE_BAUD_RATE               4
-#define CONTROL_TABLE_RETURN_DELAY_TIME       5
-#define CONTROL_TABLE_CW_ANGLE_LIMIT          6
-#define CONTROL_TABLE_CCW_ANGLE_LIMIT         8
-#define CONTROL_TABLE_TEMPERATURE_LIMIT      11
-#define CONTROL_TABLE_MIN_VOLTAGE_LIMIT      12
-#define CONTROL_TABLE_MAX_VOLTAGE_LIMIT      13
-#define CONTROL_TABLE_MAX_TORQUE             14
-#define CONTROL_TABLE_STATUS_RETURN_LEVEL    16
-#define CONTROL_TABLE_ALARM_LED              17
-#define CONTROL_TABLE_SHUTDOWN               18
-#define CONTROL_TABLE_MULTITURN_OFFSET       20
-#define CONTROL_TABLE_RESOLUTION_DIVIDER     22
-#define CONTROL_TABLE_TORQUE_ENABLE          24
-#define CONTROL_TABLE_LED                    25
-#define CONTROL_TABLE_P_GAIN                 26
-#define CONTROL_TABLE_I_GAIN                 27
-#define CONTROL_TABLE_D_GAIN                 28
-#define CONTROL_TABLE_GOAL_POSITION          30
-#define CONTROL_TABLE_MOVING_SPEED           32
-#define CONTROL_TABLE_TORQUE_LIMIT           34
-#define CONTROL_TABLE_PRESENT_POSITION       36
-#define CONTROL_TABLE_PRESENT_SPEED          38
-#define CONTROL_TABLE_PRESENT_LOAD           40
-#define CONTROL_TABLE_PRESENT_VOLTAGE        42
-#define CONTROL_TABLE_PRESENT_TEMPERATURE    43
-#define CONTROL_TABLE_REGISTRED_INSTRUCTION  44
-#define CONTROL_TABLE_MOVING                 46
-#define CONTROL_TABLE_LOCK                   47
-#define CONTROL_TABLE_PUNCH                  48
-#define CONTROL_TABLE_GOAL_ACCELERATION      73
-
-/** 
- * @brief Class to communicate with Dynamixel MX12 servomotors
- *
- * @details
- *
- *   The servomotors are daisy chained to a serial link of the target 
- *   microcontroller. The class ensures the initialization of serial link 
- *   and the management of communications mainly to control rotational
- *   speed of servomotors. 
- *
- *   Transmission of messages to the servomotors is blocking while 
- *   reception is non-blocking thanks to the use of an interrupt routine. 
- * 
- * @author Titouan Soulard (creator and maintainer until April 2021)
- * @author Bruno Denis (Doxygen documentation and code rearrangement)
- *  
- * @see Control table of Dynamixel MX12 servomotor 
- * @see https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/
- * @see Dynamixel protocol v1.0 manual
- * @see https://emanual.robotis.com/docs/en/dxl/protocol1/
- *
- * Example of class usage to send two instruction packets to servomotor #1
- * with one second gap. First ask to move at 10% of maximum speed and the 
- * stop the movement.
- *
- * @code
- * #include "mbed.h"
- * #include "MX12.h"
- * 
- * #define SERVO_TX_PIN PC_4
- * #define SERVO_RX_PIN PC_5
- * #define SERVO_BAUD 115200
- * #define SERVO_ID 1
- * 
- * #define DELAY_1000ms 1000
- * #define DELAY_1ms       1
- * 
- * MX12 servo_bus(SERVO_TX_PIN, SERVO_RX_PIN, SERVO_BAUD);
- * float relative_speed;
- * 
- * int main()
- * {
- *     // Set speed of SERVO_ID servomotor to 10% 
- *     // Send on servo_bus to SERVO_ID motor the instruction "moving speed"
- *     // with parameter 0.1 (10% of maximum speed)
- *     relative_speed = 0.1; 
- *     servo_bus.SetSpeed(SERVO_ID, relative_speed);
- *         
- *     // wait for one second
- *     thread_sleep_for(DELAY_1000ms);
- *     
- *     // set speed of SERVO_ID servomotor to 0% 
- *     relative_speed = 0.0; 
- *     servo_bus.SetSpeed(SERVO_ID, relative_speed);
- * 
- *     // infinite loop 
- *     while (true) thread_sleep_for(DELAY_1000ms);
- * }
- * @endcode
- *
- * @warning
- *   Warning: receipt of packets from servomotors has not been tested 
- *   (hardwre problem). However, sending move speed instruction is operational.
- *
- * @warning
- *   Warning: Error field of status packet if decoded by GetStatus() returns
- *   an enumation type "Status". As several errors can be reported
- *   simultaneously the type enum is not suitable (B. Denis 11/2021).
- *
- * @bug
- *   Bug: GetStatus() method has a hazardous behavior because it provides 
- *   a result by reading the content of the variable _current_frame 
- *   which can be modified at any time by the private ISR _Rx_interrupt().
- *    
- */
-class MX12 
-{
-    public:
-    
-    /** Error status occurred during the operation of servomotor.
-     *
-     * @warning 
-     *    Enumaration type is not suitable for all error status because
-     *    it can denote only one error at a time (B. Denis 11/2021)
-     */
-    enum Status {
-        InstructionError,  /**<  In case of sending an undefined instruction 
-                                 or delivering the action instruction 
-                                 without the Reg Write instruction */
-        OverloadError,     /**<  When the current load cannot be controlled 
-                                 by the set Torque */
-        ChecksumError,     /**<  When the Checksum of the transmitted 
-                                 Instruction Packet is incorrect */
-        RangeError,        /**<  When an instruction is out of the range 
-                                 for use */
-        OverheatingError,  /**<  When internal temperature of servomotor 
-                                 is out of the range of operating 
-                                 temperature set in the Control table */
-        AngleLimitError,   /**<  When Goal Position is written out of the 
-                                 range from CW Angle Limit to CCW Angle 
-                                 Limit */
-        InputVoltageError, /**<  When the applied voltage is out of the 
-                                 range of operating voltage set in the 
-                                 Control table */
-        Unknown,           /**<  Combination of several errors (Caution: 
-                                 limit of enum approach to code errors) */
-        Ok                 ///<  no error
-    };
-    
-    /** Enumeration of states of the medium acces control (MAC) 
-     *  of the master-slave protocol of the communication between  
-     *  the robot controller (master) and the servomotors (slaves).
-     */
-    enum SerialState {
-        Writing, /**< Robot controller send an "instruction packet"
-                      (request) to a servomotor */
-        Reading, /**< Robot controller receive a "status packet" from a 
-                      requested servomotor */
-        Idle     ///< Robot controller ready for a new cycle request-answer 
-    };
-    
-    /** Structure of store status packet (also known as return packet)
-     *  according tne Dynamixel protocol v1.0, which are messages sent
-     *  by servomotors to contriller in response of an instruction packet
-     */
-    struct Status_packet {
-        unsigned char raw[MX12_PACKET_MAX_SIZE]; /**< bytes received */
-        unsigned char n_byte;   /**< Number of received byte */
-        unsigned char servo_id; /**< Identifier field denoted servomotor  
-                                 *   involved in the message */
-        unsigned char length;   /**< Length field of status packet */
-        unsigned char error;    /**< Error field of status packet */
-        unsigned char n_param;  /**< Number of received parameter*/
-        unsigned char param[MX12_PACKET_MAX_SIZE]; /**< array of received
-                                                    *   parameters */
-        unsigned char received_checksum; /**< Received checksum field */
-        unsigned char calculated_checksum; /**< Calculated checksum  */
-        bool parsed;  /**< status packet is correctly parsed */
-        bool valid;   /**< received_checksum == calculated_checksum */
-    };
-
-    /** 
-     * @brief  Discrete states of the packet parser.
-     *
-     * @detail 
-     *    Each value corresponding to a field that the parser 
-     *    can identify according the Dynamixel protocol v1.0.
-     *    Enumeration include field of instruction packets
-     *    (packets sent to servomotors) and field of status packets
-     *    (packets received from servomotors).
-     */
-    enum PacketField {
-        Header1,     ///< Heading1 field of instruction or status packet
-        Header2,     ///< Heading2 field of instruction or status packet
-        Id,          ///< ID field of instruction or status packet
-        Length,      ///< Length field of status packet
-        Error,       ///< Error status field of status packet
-        Instruction, ///< Instruction field of instruction packet
-        Data,        ///< expect to read parameter fields of status packet
-        Checksum     ///< expect to read Checksum field of status packet
-    };
-
-    /** Structure to store the current state of packet parserComplement to the ParsingState enumeration to store the reading 
-     *  progress of each section of the status packet.
-     */
-    struct ParserState {
-        MX12::PacketField expected_field; ///< next expected field
-        unsigned char byte_index;  ///< index of byte already parsed
-        unsigned char param_index; ///< index of parameter already parsed
-    };
-
-    /** Create an instance of MX12 and attach it to a serial link
-     *
-     * @param tx board pin used for transmission in UART daisy chain link 
-     *           to servomotors 
-     * @param rx board pin used for reception in UART daisy chain link 
-     *           to servomotors 
-     * @param baud modulation rate of UART signal, unit: Baud
-     *           to servomotors 
-     */
-    MX12(PinName tx, PinName rx, int baud=115200);
-    
-    /** Send desired normalized speed to a specific servomotor
-     *
-     * @param mot_id a unique value in the daisy chain network to identify
-     *               each servomotor
-     * @param speed a float between -1 and 1 that represents the percentage
-     *              of maximum requested speed
-     */
-    void SetSpeed(unsigned char mot_id, float speed);
-    
-    /** Send desired ablosute speed to a specific servomotor
-     *
-     * @param mot_id a unique value in the daisy chain network to identify
-     *               each servomotor
-     * @param speed desired speed in radians per second  
-     */
-    void SetSpeed_rad_s(unsigned char mot_id, float speed);
-    
-    /** Informs about the availability of the bus for a new transmission 
-     *  of instruction packet (Method Access Control) 
-     *
-     * @returns true if bus ready for a new transmission, otherwise false
-     */
-    char IsAvailable(void);
-    
-    /**
-     * @brief     Build and send an instruction packet to a servomotor 
-     *            according Dynamixel Protocol 1.0
-     *
-     * @detail    This method is limited to only two kind of instruction :
-     *            read data from a servomoteur et write data on servomotor.
-     *            Ping, Reg Write, Action, Factory Reset, Rebbot, Sync Write
-     *            and Bulk Read are not supported.
-     *
-     *            For the method to issue a read instruction, set the data 
-     *            parameter to NULL, otherwise the method issue a 
-     *            write instruction 
-     *
-     * @param[in] mot_id indicates the ID of the device (servomotor) that
-     *            should receive the Instruction Packet and process it
-     * @param[in] address data address in the "Control Table of RAM Area"
-     *            of a servomotor MX12 
-     *            (https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/#control-table-of-ram-area).
-     * @param[in] len if it is a write instruction, size in bytes 
-     *            of the data to write in the "Control Table of RAM Area"
-     * @param[in] data array of char containing parameter of Danamixel  
-     *            protocol that are the instruction’s auxiliary data field.
-     *            Set to NULL for read instruction, otherwise the method issue 
-     *            a write instruction 
-     *  
-     * @see https://emanual.robotis.com/docs/en/dxl/protocol1/
-     *
-     * Structure of instruction Packet
-     *
-     * <PRE>
-     * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum|
-     * |-------|-------|---------|------|-----------|---------------|--------|
-     * |  0xFF |  0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM |
-     * | cmd[0]| cmd[1]|  cmd[2] |cmd[3]|  cmd[4]   |cmd[5]...      |        |
-     *                  \\__  ___/                    \\_  _/ \\__  __/
-     *                     \/                          \/      \/
-     *                   mot_id                      address   data
-     *                                                        (len = N-1)
-     * </PRE>
-     */
-    void rw(unsigned char mot_id, char address, char len, char *data);
-    
-    /** 
-     * Display status packet in hexadecimal format
-     * 
-     * @warning
-     *    Use console without any previous declaration. Assume console is 
-     *    setup by calling program
-     */
-    void PrintSerial();
-    
-    /**
-     * Get information from de Error byte of the last status packet
-     * received from a servomotor
-     *
-     * @return 
-     *    One of enum MX12::Status value to describe errors. 'Ok' is
-     *    returns if no error occurred during the last operation of
-     *    servomotor.
-     * 
-     * @warning 
-     *    Warning: if a combination of several errors is reported the function
-     *    returns "Unknown".
-     *
-     * @bug
-     *    Bug: this method has a hazardous behavior because it provides 
-     *    a result by reading the content of the variable _current_frame 
-     *    which can be modified at any time by the private ISR _Rx_interrupt()  
-     */
-     
-    MX12::Status GetStatus(void);
-    
-    
-    // Allow to read the status packet
-    char ReadSerial();
-
-    /* function aivailaible in a previous version of the class 
-     */
-    // MX12::Status GetStatus(void);
-    // void ReadPosition(unsigned char mot_id);
-    // float GetPosition(unsigned char mot_id);
-    
-    void cmd_moteur(float Vavance, float Vlat, float Wz);
-    // envoie la commande moteur de manière à avancer d'une vitesse Vavance en 
-    // mètres par seconde, d'une vitesse Vlat en mètre par seconde et d'une 
-    // vitesse de rotation Wz en rad/s
-    
-    void eteindre_moteurs();
-    // permet d'enlever le couple dans les moteurs
-    
-    void cmd_moteur_multiturn(float pos1, float pos2, float pos3);
-    // permet de positionner le moteur pas à pas
-    
-    void cmd_moteur_rampe_unitaire(int id_moteur, float w_moteur, int step, float time);
-                
-    protected:
-    
-    /** Serial port where servomotor bus is connected
-     */
-    UnbufferedSerial _mx12;
-    
-    
-    /** Servomotor bus state to managed medium acces control (MAC)
-     */
-    MX12::SerialState _bus_state;
-    
-    /** Structure filled by ISR (Interrupt Service Routine) ReadCallback()
-     *  parser to store message received from servomotor byte after byte 
-     */
-    MX12::Status_packet _status_pck;
-    
-    /** Structure update by ISR (Interrupt Service Routine) ReadCallback()
-     *  parser to model its current state
-     */
-    MX12::ParserState _parser_state;
-
-            
-    unsigned char _answer;
-                
-    /** 
-     * @brief  
-     *    Interupt service routine (ISR) to read and parse received message
-     *
-     * @detail
-     *    This interupt routine is attached to reception event on servomoteur 
-     *    bus and is called for each character received on bus. 
-     *
-     *    As the characters are received, the progress of the parser 
-     *    is stored in _parser_state and the result of the analysis 
-     *    is stored in _status_pck.
-     */
-    void _Rx_interrupt();
-    
-};
-
-#endif /* MBED_MX12_H_ */
\ No newline at end of file