Difference between revisions of "1DOF Haptic"

From RobolaboWiki
Jump to: navigation, search
 
(27 intermediate revisions by 2 users not shown)
Line 5: Line 5:
  
 
<h1> Configuring the environment  </h1>
 
<h1> Configuring the environment  </h1>
 +
  
 
<h2> Setting up the Arduino Software </h2>
 
<h2> Setting up the Arduino Software </h2>
  
 
<ul>
 
<ul>
<li> Download the Arduino IDE 1.6.x according to your operating system from: https://www.arduino.cc/en/Main/Software . </li>
+
<li> Download the Arduino IDE according to your operating system from: https://www.arduino.cc/en/Main/Software . </li>
 
<li> Install the Arduino IDE </li>
 
<li> Install the Arduino IDE </li>
 
<ul>
 
<ul>
Line 21: Line 22:
 
<h2> Installing Tools and Libraries </h2>
 
<h2> Installing Tools and Libraries </h2>
 
<ul>
 
<ul>
<li> The 1DOF haptic robot uses a Arduino DUE board, so we need to install it on the Arduino IDE. Open Boards configurator: </li>
+
<li> The 1DOF haptic robot uses a Arduino DUE board, so the Arduino IDE support must be installed. Open Boards configurator: </li>
 
<pre>
 
<pre>
 
Tools &rarr; Boards &rarr; Boards' Manager
 
Tools &rarr; Boards &rarr; Boards' Manager
Line 33: Line 34:
 
</pre>
 
</pre>
  
<li> Select the zip file were have been downloaded </li>
+
<li> Select the zip file that has been downloaded </li>
  
 
<h3> Installing FTDI drivers </h3>
 
<h3> Installing FTDI drivers </h3>
Line 43: Line 44:
  
 
We have created a helloWorld example to test the communication with the robot.
 
We have created a helloWorld example to test the communication with the robot.
Please download it from [[media:1DOFHAP-HelloWorldMotor.tgz | here ]] in your prefered destination.
+
Please download it from [[http://www.robolabo.etsit.upm.es/wikiFiles/1DOFHAP-HelloWorldMotor.tgz here ]] in your prefered destination.
 
Untar the file:
 
Untar the file:
 
<pre>
 
<pre>
Line 109: Line 110:
  
 
For the implementation of Practice 2 of the "Control and Robotics in Medicine" subject of the "Master on Bioengineering"  of the UPM, we have created a students template.
 
For the implementation of Practice 2 of the "Control and Robotics in Medicine" subject of the "Master on Bioengineering"  of the UPM, we have created a students template.
You can download the template from [[media:1DOFHAP-P2Template.tgz | here ]]
+
You can download the template from [[http://www.robolabo.etsit.upm.es/wikiFiles/1DOFHAP-P2Template.tgz here ]]
  
 
<h2> Structure </h2>  
 
<h2> Structure </h2>  
 
The template has 5 different block of files:
 
The template has 5 different block of files:
 
<ul>
 
<ul>
<li> <b> encoder.{c,h} </b>: where functions related to the measurement of encoder are developed.
+
<li> <b> encoder.{c,h} </b>: where functions related to the measurement of the encoder are developed.
 
<li> <b> motor.{c,h} </b>: where functions related to the movement of the motor are developed.
 
<li> <b> motor.{c,h} </b>: where functions related to the movement of the motor are developed.
 
<li> <b> comm.{c,h} </b>: where functions related to the serial port communication are developed.
 
<li> <b> comm.{c,h} </b>: where functions related to the serial port communication are developed.
 
<li> <b> controller.{c,h} </b>: where specific controllers could be developed. <b> It will not be used on P2 </b>
 
<li> <b> controller.{c,h} </b>: where specific controllers could be developed. <b> It will not be used on P2 </b>
<li> <b> P2Template.ino </b>: The place where the practice should be developed.
+
<li> <b> P2-Template.ino </b>: The place where the practice should be developed.
 
</ul>
 
</ul>
  
Line 134: Line 135:
 
The functions to control the encoder are defined as follows:
 
The functions to control the encoder are defined as follows:
  
 +
<!--<li> <b> void ENCODER_Init (void) </b>: It configures the pinout of the encoder and launches the interrupts related to channel A and B. </li>-->
 +
<pre>
 +
void ENCODER_Init (void)
 +
</pre>
 +
It configures the pinout of the encoder and launches the interrupts related to channel A and B.
 +
<br>
  
<ul>
+
 
<li> <b> void ENCODER_Init (void) </b>: It configures the pinout of the encoder and launches the interrupts related to channel A and B. </li>
+
<!--<li> <b> void ENCODER_StartSpeedCalculation  ( long l_sampling_time ) </b>: It configures a timer in charge of calculating the speed average of the motor. </li> -->
<li> <b> void ENCODER_StartSpeedCalculation  ( long l_sampling_time ) </b>: It configures a timer in charge of calculating the speed average of the motor. </li>
+
<pre>
 +
void ENCODER_StartSpeedCalculation  ( long l_sampling_time )
 +
</pre>
 +
It configures a timer in charge of calculating the speed average of the motor.
 
<ul>
 
<ul>
 
   <li> <b> long l_sampling_time </b>: It defines the sampling period in milliseconds.
 
   <li> <b> long l_sampling_time </b>: It defines the sampling period in milliseconds.
 
</ul>  
 
</ul>  
<li> <b> long ENCODER_GetCount ( void ) </b>: It returns the actual count of the encoder, that is, the position of the motor related to its initial condition. </li>
+
<br>
 +
 
 +
<!--<li> <b> long ENCODER_GetCount ( void ) </b>: It returns the actual count of the encoder, that is, the position of the motor related to its initial condition. </li>-->
 +
<pre>
 +
long ENCODER_GetCount ( void )
 +
</pre>
 +
It returns the actual count of the encoder, that is, the position of the motor related to its initial condition.
 
<ul>
 
<ul>
 
   <li> <b> return </b>: It returns a long value related to the pulses of the encoder, positive or negative, related to the initial position of the encoder. </li>
 
   <li> <b> return </b>: It returns a long value related to the pulses of the encoder, positive or negative, related to the initial position of the encoder. </li>
 
</ul>
 
</ul>
<li> <b> long ENCODER_GetCountInSpeedInterval ( void) </b>: It returns an averge speed, expressed in counts per second. </li>
+
<br>
 +
 
 +
<!--<li> <b> long ENCODER_GetCountInSpeedInterval ( void) </b>: It returns an averge speed, expressed in counts per second. </li>-->
 +
<pre>
 +
long ENCODER_GetCountInSpeedInterval ( void)
 +
</pre>
 +
It returns an averge speed, expressed in counts per second.
 +
 
 
<ul>
 
<ul>
 
<li> <b> return </b>: It returns a long value related to the pulses per second of the encoder, positive or negative.
 
<li> <b> return </b>: It returns a long value related to the pulses per second of the encoder, positive or negative.
</ul>
 
 
</ul>
 
</ul>
 +
 +
<br>
 +
<b> IMPORTANT: The encoder available on Practice 2, is a 48 quadrature Counts Per Revolution (CPR) encoder.
 +
This means that <i> ENCODER_GetCount (void) </i> and <i> ENCODER_GetCountInSpeedInterval (void) </i> functions return a value related to the encoder counts.
 +
That means that for every turn on the motor axis, there are 48 values (1 pulse every 7.5 degrees).
 +
This value must be multiplied by the reduction ratio of the motor to check the position outside the motor axis. </b>
 +
<br>
  
 
<h3> Motor </h3>
 
<h3> Motor </h3>
  
 
This library is in charge of moving the motor.  
 
This library is in charge of moving the motor.  
The motor is moved based on PWM which is executed at a sampling period.
+
The motor is moved based on a PWM which is executed at a sampling period.
  
 
The functions to control the motor are defined as follows:
 
The functions to control the motor are defined as follows:
  
<ul>
+
<!-- <li> <b> void MOTOR_Init ( void ) </b>: It configures the pinout of the H-bridge to control the motor and inits the PWM peripheral to control it. </li> -->
<li> <b> void MOTOR_Init ( void ) </b>: It configures the pinout of the H-bridge to control the motor and inits the PWM peripheral to control it. </li>
+
<pre>
<li> <b> void MOTOR_SetVoltage ( float f_voltage ) </b>: If sets up a voltage to be sent to the motor. Remember the motor is controlled through a PWM, so it really sets up a PWM to controlthe H-Bridge.
+
void MOTOR_Init ( void )
 +
</pre>
 +
It configures the pinout of the H-bridge to control the motor and inits the PWM peripheral to control it.
 +
<br>
 +
 
 +
 
 +
<!--<li> <b> void MOTOR_SetVoltage ( float f_voltage ) </b>: It sets up a voltage to be sent to the motor. Remember the motor is controlled through a PWM, so it really sets up a PWM to controlthe H-Bridge. -->
 +
<pre>
 +
void MOTOR_SetVoltage ( float f_voltage )
 +
</pre>
 +
It sets up a voltage to be sent to the motor. Remember the motor is controlled through a PWM, so it really sets up a PWM to controlthe H-Bridge.
 +
 
 
<ul>
 
<ul>
 
   <li> <b> flot f_voltage </b>: This is the value of the voltage to be applied to the motor. It can be positive or negative, and the function limits the maximum and minimum values according to the <i> MOTOR_MAX_VOLTAGE </i> variable defined in <i> motor.h </i> </li>
 
   <li> <b> flot f_voltage </b>: This is the value of the voltage to be applied to the motor. It can be positive or negative, and the function limits the maximum and minimum values according to the <i> MOTOR_MAX_VOLTAGE </i> variable defined in <i> motor.h </i> </li>
 
</ul>
 
</ul>
</ul>
+
<br>
  
  
 
<h3> Communication </h3>
 
<h3> Communication </h3>
<h3> Controller </h3>
 
<h3> P2Template.ino </h3>
 
  
*******************************
+
This library is in charge of managing periodic communications through the serial port.
*******************************
+
The functions are defined as follows:
  
  
 
+
<!--<li> <b> void COMMUNICATION_Init ( int speed )</b>: It configures the serial port at a specific speed. </li> -->
<ul>
+
<li> <b> void ROBOT_GripperOpen(void) </b>: It opens the gripper, so it can release an object if already grasped.
+
<li> <b> void ROBOT_GripperClose(void) </b>: It close the gripper, so it can grasp an object if correctly located.
+
<li> <b> void ROBOT_SetSingleTrajectory ( double *f_pos, uint16_t un_time, uint8_t un_trajectory_type ) </b>: It performs a trajectory form one point (Q(t<sub>0</sub>)) to another point (Q(t<sub>f</sub>)).
+
Q(t<sub>0</sub>) and Q(t<sub>f</sub>) are defined as generalized coordinates Q={q<sub>1</sub>,q<sub>2</sub>,q<sub>3</sub>,q<sub>4</sub>,q<sub>5</sub>}.
+
Moreover, Q(t<sub>0</sub>) is defined as the coordinates at which the robot is located once the instruction is set.
+
 
+
<ul>
+
<li> <b>double *f_pos </b>:
+
Q(t<sub>f</sub>) is coded as <i> double * </i>, for example:
+
 
<pre>
 
<pre>
double m_fCoordTest[]      = {0,M_PI/2,-M_PI/2,0,0};
+
void COMMUNICATION_Init ( int speed );
 
</pre>
 
</pre>
 
+
It configures the serial port at a specific speed.
<li> <b> uint16_t un_time </b>, represents the time that it takes to travel from  (Q(t<sub>0</sub>)) to Q(t<sub>f</sub>),that is: t<sub>f</sub> - t<sub>0</sub> in milliseconds.
+
<ul>
 
+
  <li> <b> int speed </b>: The speed, in bauds, to configure and open the serial port. </li>
<li> <b> uint8_t un_trajectory_type </b>, represents the type of trajectory to perform: Linear (LINEAR = 0)  or Cubic  (CUBIC1 = 1)
+
</ul>
 
+
 
<br>
 
<br>
<br>
 
Therefore, if we want to move the robot for the actual position to position <i> m_fCoordTest </i> taking 2 seconds with a linear function, we need to execute:
 
  
 +
<!-- <li> <b> void COMMUNICATION_Start ( long l_sampling_time ) </b>: It starts a timer to handle periodically the communications. This timer calls the <i> COMMUNICATION_ROB </i> function at <i> l_sampling_time </i> </li> -->
 
<pre>
 
<pre>
ROBOT_SetSingleTrajectory (m_fCoordTest, 2000, LINEAR);
+
void COMMUNICATION_Start ( long l_sampling_time )
</pre>
+
 
+
I we want to move the robot to the same coordinates but in 10 secons with a cubic function, we need to execute:
+
<pre>
+
ROBOT_SetSingleTrajectory (m_fCoordTest, 10000, CUBIC1);
+
 
</pre>
 
</pre>
 +
It starts a timer to handle periodically the communications. This timer calls the <i> COMMUNICATION_ROB </i> function at <i> l_sampling_time </i>
  
 +
<ul>
 +
<li> <b> long l_sampling_time </b>: It defines the sampling period in milliseconds.</li>
 
</ul>
 
</ul>
<li> <b> void ROBOT_SetDoubleTrajectory ( double *un_pos1, double *un_pos2, uint16_t un_time1, uint16_t un_time2, uint8_t un_trajectory_type ) </b>:
+
<br>
It performs a trajectory form one point (Q(t<sub>0</sub>)) to another point (Q(t<sub>f</sub>)) passing by a point (Q(t<sub>v</sub>)).
+
  
Q(t<sub>0</sub>), Q(t<sub>f</sub>) and Q(t<sub>v</sub>) are defined as generalized coordinates Q={q<sub>1</sub>,q<sub>2</sub>,q<sub>3</sub>,q<sub>4</sub>,q<sub>5</sub>}.
+
<!--<li> <b> void COMMUNICATION_Stop ( void ) </b>: It stops the timer in charge of calling <i> COMMUNICATION_ROB </i>, so communication stops. </li> -->
Moreover, Q(t<sub>0</sub>) is defined as the coordinates at which the robot is located once the instruction is set.
+
 
+
<ul>
+
<li> <b>double *f_pos1 </b>:
+
Q(t<sub>v</sub>) is coded as <i> double * </i> , for example:
+
 
<pre>
 
<pre>
double m_fCoordTest[]      = {0,M_PI/2,-M_PI/2,0,0};
+
void COMMUNICATION_Stop ( void )
 
</pre>
 
</pre>
 +
It stops the timer in charge of calling <i> COMMUNICATION_ROB </i>, so communication stops.
  
<li> <b>double *f_pos2 </b>:
 
Q(t<sub>v</sub>) is coded as <i> double * </i>.
 
  
<li> <b> uint16_t un_time1 </b>,  represents the time that it takes to travel from  (Q(t<sub>0</sub>)) to Q(t<sub>v</sub>),that is: t<sub>v</sub> - t<sub>0</sub> in milliseconds.
+
<h3> Controller </h3>
<li> <b> uint16_t un_time2 </b>,  represents the time that it takes to travel from  (Q(t<sub>v</sub>)) to Q(t<sub>f</sub>),that is: t<sub>f</sub> - t<sub>v</sub> in milliseconds.
+
This library is in charge of managing a periodic timer to implement the controller developed.
 
+
The functions are defined as follows:
<li> <b> uint8_t un_trajectory_type </b>, represents the type of trajectory to perform. Only cubic trajectories are allowed  (CUBIC2 = 2)
+
 
+
<br>
+
<br>
+
Therefore, if we want to move the robot for the actual position to position <i> m_fCoordTest </i>  taking 5 seconds passing by <i> m_fCoordVia </i> with 2 seconds from the start, we need to execute:
+
  
 +
<!--<li> <b> void CONTROLLER_Start ( long l_sampling_time ) </b>: It starts a timer to handle periodically the communications. This timer calls the <i> CONTROLLER_ROB </i> function at <i> l_sampling_time </i></li>-->
 
<pre>
 
<pre>
ROBOT_SetDoubleTrajectory (m_fCoordVia, m_fCoordTest, 2000, 3000, CUBIC2);
+
void CONTROLLER_Start ( long l_sampling_time )
 
</pre>
 
</pre>
 +
It starts a timer to handle periodically the communications. This timer calls the <i> CONTROLLER_ROB </i> function at <i> l_sampling_time </i>
  
 +
<ul>
 +
<li> <b> long l_sampling_time </b>: It defines the sampling period in milliseconds.</li>
 
</ul>
 
</ul>
</ul>
+
<br>
  
<h2> Implementation </h2>
 
  
<i> P1-Template.ino </i> follows the same structure as the helloWorld.ino example.
+
<h3> P2-Template.ino </h3>
However, a new option has been included in the menu (Opcion A).
+
This option calls the <i> P1Solution </i> method.
+
If you open <i> P1-Template.ino </i> and go to the end of the file, you will see the following code:
+
  
 +
<!-- <li> <b> void COMMUNICATION_ROB ( void ) </b>: In this function you should implement which is the information you want to send through the serial port, to obtain specific data and plot some graphs. </li> -->
 
<pre>
 
<pre>
void P1Solution ( void )
+
void COMMUNICATION_ROB ( void )
{
+
</pre>
  /* START CODE TO BE IMPLEMENTED BY THE STUDENTS */
+
This function should implement which is the information you want to send through the serial port, to obtain specific data and plot some graphs.
 
+
<br>
  /* END CODE TO BE IMPLEMENTED BY THE STUDENTS */
+
}
+
  
 +
<!--<li> <b> void CONTROLLER_ROB ( void )</b>: In this function you should implement your controllers. </li>-->
 +
<pre>
 +
void CONTROLLER_ROB ( void )
 
</pre>
 
</pre>
 +
This function should implement the controllers.
  
It is between those comments where you must implement all functions required to achive the task.
+
<b> Important </b>: It is important that the helloworld and template files are studied before starting Practice 2.
Remember you may need some <i> delay </i> instructions, defined as <i> void delay (uint16_t millisec) </i>, to prevent some instructions to execute before you need them.
+
Moreover, it is recommended that before arriving to the laboratory, two functions to convert encoder counts to position (in radians) and speed (in radians/second) are already programmed, to save time and get a basic understanding of the robot electronics.
 
+
<br>
+
Moreover, in the <i> poses.h </i> file you can find some examples of how to define the generalized coordinates of your system.
+

Latest revision as of 19:50, 1 June 2023

Note: The electronics of the robot are based on a Arduino Due board: https://www.arduino.cc/en/Main/ArduinoBoardDue Moreover, the motor control is done through a H-Bridge board from ST: http://www.st.com/en/ecosystems/x-nucleo-ihm04a1.html

Configuring the environment


Setting up the Arduino Software

  • Download the Arduino IDE according to your operating system from: https://www.arduino.cc/en/Main/Software .
  • Install the Arduino IDE
    • If you have chosen to download the installer, run the installer and install the software in a path of your convenience.
    • If you have chosen to download the sources (Linux or zip on Windows), uncompress the software in a path of your convenience
  • Open/run Arduino IDE, so it will create all the folders needed

Installing Tools and Libraries

  • The 1DOF haptic robot uses a Arduino DUE board, so the Arduino IDE support must be installed. Open Boards configurator:
  • Tools → Boards → Boards' Manager
    

    Install support for SAM Boards - (32-bits ARM Cortex-M3

  • Download the DueTimer.zip library from: https://github.com/ivanseidel/DueTimer/releases
  • Install the library:
  • Program → Include library → Add Zip library
    
  • Select the zip file that has been downloaded
  • Installing FTDI drivers

    If you are using Linux or Mac, skip this step. If you are using Windows, power up the robot and connect it to your computer. Windows should ask you to install some FTDI drivers to be able to connect to the robot.

    Hello World example

    We have created a helloWorld example to test the communication with the robot. Please download it from [here ] in your prefered destination. Untar the file:

    tar -xvzf helloWorld.tgz
    

    Compiling the code

  • Open Arduino IDE and load the .ino file in your environment:
  • File → Open → <HELLOWORLD_EXAMPLE>
    
  • Select the Arduino DUE board:
  • Tools → Board → Arduino Due
    
  • Compile the program:
  • Program → Verify/Compile
    

    Downloading the code to the robot

    The Arduino Due has two usb ports. The one that is closer to the power jack is the programming port and the one used with the 1DOF Haptic Robot.

    Select the correct port to download the binaries: In Linux, typically:

    tools → Port → /dev/ttyUSBX
    

    In Windows, typically:

    tools → Port → COMX
    

    where X depends on your system and the number of peripherals on it

    Upload your code to the board:

    Program → Upload
    

    The IDE will notify that it is uploading and after some seconds it will say uploaded .

    Playing with HelloWorld

    This example allows you to see the functionality of some of the functions handcoded. Once the software has been loaded, the robot should move 1 second counterclockwise and 1 second clockwise. After those 2 seconds it should stop.

    Once the code have been loaded, you can open the serial port:

    Tools → Serial Monitor
    

    You should see in real time the information provided by the helloworld example, basically:

    • Count: The communication time, in timer ticks
    • Pos: The position, in encoder pulses units
    • Vel: The speed, in encoder pulses units

    Practice 2 Template (P2)

    For the implementation of Practice 2 of the "Control and Robotics in Medicine" subject of the "Master on Bioengineering" of the UPM, we have created a students template. You can download the template from [here ]

    Structure

    The template has 5 different block of files:

    • encoder.{c,h} : where functions related to the measurement of the encoder are developed.
    • motor.{c,h} : where functions related to the movement of the motor are developed.
    • comm.{c,h} : where functions related to the serial port communication are developed.
    • controller.{c,h} : where specific controllers could be developed. It will not be used on P2
    • P2-Template.ino : The place where the practice should be developed.

    Methods

    This Section provides important information for the resolution of Practice2. It is based on the explanation of different methods to control the robot, but it does not explain the complete set of methods. To get and exahustive description of all methods all fies must be studied.

    Given some restrictions to the Arduino software structure, some function prototypes are defined in the main file. However, sections related to the header files refer to its implementation.

    Encoder

    This library is in charge of calculating the movement of the motor related to the encoder. The functions to control the encoder are defined as follows:

    void ENCODER_Init (void)
    

    It configures the pinout of the encoder and launches the interrupts related to channel A and B.


    void ENCODER_StartSpeedCalculation  ( long l_sampling_time )
    

    It configures a timer in charge of calculating the speed average of the motor.

    • long l_sampling_time : It defines the sampling period in milliseconds.


    long ENCODER_GetCount ( void )
    

    It returns the actual count of the encoder, that is, the position of the motor related to its initial condition.

    • return : It returns a long value related to the pulses of the encoder, positive or negative, related to the initial position of the encoder.


    long ENCODER_GetCountInSpeedInterval ( void)
    

    It returns an averge speed, expressed in counts per second.

    • return : It returns a long value related to the pulses per second of the encoder, positive or negative.


    IMPORTANT: The encoder available on Practice 2, is a 48 quadrature Counts Per Revolution (CPR) encoder. This means that ENCODER_GetCount (void) and ENCODER_GetCountInSpeedInterval (void) functions return a value related to the encoder counts. That means that for every turn on the motor axis, there are 48 values (1 pulse every 7.5 degrees). This value must be multiplied by the reduction ratio of the motor to check the position outside the motor axis.

    Motor

    This library is in charge of moving the motor. The motor is moved based on a PWM which is executed at a sampling period.

    The functions to control the motor are defined as follows:

    void MOTOR_Init ( void )
    

    It configures the pinout of the H-bridge to control the motor and inits the PWM peripheral to control it.


    void MOTOR_SetVoltage ( float f_voltage )
    

    It sets up a voltage to be sent to the motor. Remember the motor is controlled through a PWM, so it really sets up a PWM to controlthe H-Bridge.

    • flot f_voltage : This is the value of the voltage to be applied to the motor. It can be positive or negative, and the function limits the maximum and minimum values according to the MOTOR_MAX_VOLTAGE variable defined in motor.h



    Communication

    This library is in charge of managing periodic communications through the serial port. The functions are defined as follows:


    void COMMUNICATION_Init ( int speed );
    

    It configures the serial port at a specific speed.

    • int speed : The speed, in bauds, to configure and open the serial port.


    void COMMUNICATION_Start ( long l_sampling_time )
    

    It starts a timer to handle periodically the communications. This timer calls the COMMUNICATION_ROB function at l_sampling_time

    • long l_sampling_time : It defines the sampling period in milliseconds.


    void COMMUNICATION_Stop ( void )
    

    It stops the timer in charge of calling COMMUNICATION_ROB , so communication stops.


    Controller

    This library is in charge of managing a periodic timer to implement the controller developed. The functions are defined as follows:

    void CONTROLLER_Start ( long l_sampling_time )
    

    It starts a timer to handle periodically the communications. This timer calls the CONTROLLER_ROB function at l_sampling_time

    • long l_sampling_time : It defines the sampling period in milliseconds.



    P2-Template.ino

    void COMMUNICATION_ROB ( void )
    

    This function should implement which is the information you want to send through the serial port, to obtain specific data and plot some graphs.

    void CONTROLLER_ROB ( void )
    

    This function should implement the controllers.

    Important : It is important that the helloworld and template files are studied before starting Practice 2.

    Moreover, it is recommended that before arriving to the laboratory, two functions to convert encoder counts to position (in radians) and speed (in radians/second) are already programmed, to save time and get a basic understanding of the robot electronics.