PSL_2021 / servomotor_MX12_Lorenzo

Dependents:   PSL_ROBOT_lorenzo robot_lorenzo recepteur_mbed_os_6

Revision:
13:ccda9a56fef1
Parent:
12:acfd6c46954b
Child:
14:5a0c7b30f8c0
--- a/MX12.h	Sat Nov 06 17:42:25 2021 +0000
+++ b/MX12.h	Sun Nov 07 10:36:06 2021 +0000
@@ -1,16 +1,15 @@
 /**  
  * @file MX12.h
- * @brief this header file will contain all required definitions and 
+ * @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_DATA_MAX_SIZE 256
+#define MX12_PACKET_MAX_SIZE 32
 #define MX12_MAX_MOTOR_COUNT 16
 
 /* Dynamixel protocol v1.0 : Instructions
@@ -131,14 +130,9 @@
  *
  * @bug
  *
- *   Bug: _frame_pointer variable is used by private _ReadCallback() ISR 
- *   to store the current size for message (status packet) received from 
- *   servomotor. This variable is NOT initialised and NEVER reset to zero 
- *   at each new message.
- *
  *   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 _ReadCallback().
+ *   which can be modified at any time by the private ISR _Rx_interrupt().
  *    
  */
 class MX12 
@@ -175,9 +169,9 @@
         Ok                 ///<  no error
     };
     
-    /** Enumeration of states of the acces methode of the master-slave 
-     *  protocol of the communication between the robot controller (master) 
-     *  and the servomotors (slaves).
+    /** 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"
@@ -191,33 +185,50 @@
      *  according tne Dynamixel protocol v1.0, which are messages sent
      *  by servomotors to contriller in response of an instruction packet
      */
-    struct Frame {
-        unsigned char motorId; /**< Identifier of the servomotor involved 
-                                    in this exchange */
-        unsigned char length;  /**< */
-        unsigned char data[MX12_DATA_MAX_SIZE]; /**< */
-        unsigned char valid;   /**< */
+    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 */
     };
 
-    /** State of packet parser store which section of a status packet 
-     *  (according the Dynamixel according the Dynamixel) is currently reading
-     *  from a servomotor return message.
+    /** 
+     * @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 ParsingState {
-        Header,    ///< reading the two heading bytes
-        Id,        ///< reading the servomotor ID byte
-        Length,    ///< reading byte length of the instruction
-        Data,      ///< reading parameters
-        Checksum   ///< reading one bytes checksum 
+    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
     };
 
-    /** Complement to the ParsingState enumeration to store the reading 
+    /** 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 StateContext {
-        unsigned char headingCount;
-        unsigned char dataCount;
-        unsigned char checksum;
+    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 MX12 instance
@@ -248,9 +259,17 @@
     char IsAvailable(void);
     
     /**
-     * Build and send an instruction packet to a servomotor according
-     * DYNAMIXEL Protocol 1.0 (online protocol documentation 
-     * https://emanual.robotis.com/docs/en/dxl/protocol1/)
+     * @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
@@ -260,11 +279,14 @@
      * @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
+     *            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/
      *
-     * Packet sent
+     * Structure of instruction Packet
+     *
      * <PRE>
      * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum|
      * |-------|-------|---------|------|-----------|---------------|--------|
@@ -278,10 +300,12 @@
      */
     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();
     
@@ -303,7 +327,7 @@
      *
      *    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 _ReadCallback()  
+     *    which can be modified at any time by the private ISR _Rx_interrupt()  
      */
     MX12::Status GetStatus(void);
 
@@ -315,43 +339,42 @@
                 
     protected:
     
-    /*
+    /** Serial port where servomotor bus is connected
      */
     UnbufferedSerial _mx12;
-    MX12::ParsingState _pstate;
-    MX12::SerialState _sstate;
+    
+    
+    /** Servomotor bus state to managed medium acces control (MAC)
+     */
+    MX12::SerialState _bus_state;
     
-    /** Structure used only by ISR (Interrupt Service Routine) ReadCallback() 
+    /** Structure filled by ISR (Interrupt Service Routine) ReadCallback()
+     *  parser to store message received from servomotor byte after byte 
      */
-    MX12::StateContext _scontext;
-    MX12::Frame _current_frame;
+    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;
-    
-    /** Character array to store status message received from servomotors.
-     *  _ReadCallback() ISR fill this array character by character and 
-     *  update the size of the message currently received in the variable
-     *  _frame_pointer.
-     */
-    unsigned char _stored_frame[MX12_DATA_MAX_SIZE];
-    
-    /** Size of the message currently received from servomotor. This variable
-     *  is update at each call of _ReadCallback() ISR. The content of the
-     *  message is store into _stored_frame array.
+                
+    /** 
+     * @brief  
+     *    Interupt service routine (ISR) to read and parse received message
+     *
+     * @detail
      *
-     *  @warning
+     *    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.
      */
-    unsigned char _frame_pointer;
-                
-    /** Interupt service routine (ISR) to read and parse the response message
-     *  comming from servomotor on UART (serial port). This routine is called 
-     *  when each character is received on the servomotor bus. 
-     *
-     *  As the characters are received, the progress of the parser 
-     *  is stored in the two state variables _pstate and _scontext,
-     *  and the result of the analysis is stored in _current_frame. 
-     */
-    void _ReadCallback();
+    void _Rx_interrupt();
     
 };