pepe

Dependencies:   mbed Matrix

Files at this revision

API Documentation at this revision

Comitter:
PedroMartins96
Date:
Wed Mar 13 23:04:14 2019 +0000
Child:
1:2716ea33958b
Commit message:
444

Changed in this revision

Communication.cpp Show annotated file Show diff for this revision Revisions of this file
Communication.h Show annotated file Show diff for this revision Revisions of this file
MessageBuilder.cpp Show annotated file Show diff for this revision Revisions of this file
MessageBuilder.h Show annotated file Show diff for this revision Revisions of this file
Robot.cpp Show annotated file Show diff for this revision Revisions of this file
Robot.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Communication.cpp	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,36 @@
+#include "Communication.h"
+#include "mbed.h"
+#include "MessageBuilder.h"
+ 
+const char max_len = 30;
+Serial *serial_object;
+MessageBuilder bin_msg;
+ 
+void init_communication(Serial *serial_in)
+{
+    serial_object = serial_in;
+}
+ 
+void write_bytes(char *ptr, unsigned char len)
+{
+    for(int i=0; i<len; i++)
+    {
+        serial_object->putc(ptr[i]);
+    }
+}
+ 
+void send_odometry(int value1, int value2, int ticks_left, int ticks_right, float x, float y, float theta)
+{
+    bin_msg.reset();
+    bin_msg.add('O');
+    bin_msg.add(value1);
+    bin_msg.add(value2);
+    bin_msg.add(ticks_left);
+    bin_msg.add(ticks_right);
+    bin_msg.add(x);
+    bin_msg.add(y);
+    bin_msg.add(theta);
+ 
+    write_bytes(bin_msg.message, bin_msg.length());
+}
+     
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Communication.h	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,11 @@
+#ifndef COMMUNICATION_H
+#define COMMUNICATION_H
+ 
+#include "mbed.h"
+ 
+void init_communication(Serial *serial_in);
+void write_bytes(char *ptr, unsigned char len);
+void send_odometry(int value1, int value2, int ticks_left, int ticks_right, float x, float y, float theta);
+ 
+#endif
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MessageBuilder.cpp	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,77 @@
+#include "MessageBuilder.h"
+#include "mbed.h"
+ 
+MessageBuilder::MessageBuilder() {
+    reset();
+}
+ 
+MessageBuilder::~MessageBuilder() {
+    // TODO Auto-generated destructor stub
+}
+ 
+char MessageBuilder::add(const void* data, size_t len) {
+    if (available() >= len) {
+        memcpy(_pointer, data, len);
+        _pointer += len;
+        return 0;
+    } else {
+        return 1;
+    }
+}
+ 
+void MessageBuilder::reset() {
+    message[0] = 0x06;
+    message[1] = 0x85;
+    _pointer = &message[2];
+}
+ 
+// Note: if message size grow beyond 32 bytes, return "size_t" insted, because it
+// is the most appropriate type for "sizeof" operator. Now, unsgined char is used
+// for memory economy.
+unsigned char MessageBuilder::available() {
+    return &message[max_len - 1] - _pointer + 1;
+}
+ 
+unsigned char MessageBuilder::length() {
+    return _pointer - &message[0];
+}
+ 
+char MessageBuilder::add(float data) {
+    if (available() >= sizeof(data)) {
+        memcpy(_pointer, &data, sizeof(data));
+        _pointer += sizeof(data);
+        return 0;
+    } else {
+        return 1;
+    }
+}
+ 
+char MessageBuilder::add(int data) {
+    if (available() >= sizeof(data)) {
+        memcpy(_pointer, &data, sizeof(data));
+        _pointer += sizeof(data);
+        return 0;
+    } else {
+        return 1;
+    }
+}
+ 
+char MessageBuilder::add(char data) {
+    if (available() >= sizeof(data)) {
+        memcpy(_pointer, &data, sizeof(data));
+        _pointer += sizeof(data);
+        return 0;
+    } else {
+        return 1;
+    }
+}
+ 
+char MessageBuilder::add(unsigned int data) {
+    if (available() >= sizeof(data)) {
+        memcpy(_pointer, &data, sizeof(data));
+        _pointer += sizeof(data);
+        return 0;
+    } else {
+        return 1;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MessageBuilder.h	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,29 @@
+#ifndef MESSAGEBUILDER_H_
+#define MESSAGEBUILDER_H_
+ 
+#include "mbed.h"
+ 
+class MessageBuilder
+{
+private:
+    static const char max_len = 32;
+    char *_pointer;
+ 
+public:
+    char message[max_len];
+ 
+    MessageBuilder();
+    virtual ~MessageBuilder();
+    char add(const void* data, size_t len);
+    char add(char data);
+    char add(float data);
+    char add(int data);
+    char add(unsigned int data);
+    void reset();
+    unsigned char available();
+    unsigned char length();
+};
+ 
+#endif /* MESSAGEBUILDER_H_ */
+ 
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Robot.cpp	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,224 @@
+#include "Robot.h"
+#include "mbed.h"
+
+Serial PC(SERIAL_TX, SERIAL_RX);
+I2C i2c(I2C_SDA, I2C_SCL );
+const int addr8bit = 20 << 1; // 7bit I2C address is 20; 8bit I2C address is 40 (decimal).
+
+int16_t countsLeft = 0;
+int16_t countsRight = 0;
+float De=0, Dd=0, pi=3.141529, Ldis=14.2, r=6.95/2, theta=0, teta=0, x=50, y=10, D=0, Wee=0, Wdd=0, v=0, w=0;
+
+
+////////////////////////////////////////
+// Movimento para uma pose arbitrária //
+////////////////////////////////////////
+void to_pos(float x2,float y2,float phi2)
+{
+    while(1){
+    float alfa,beta,a=33,b=30;
+    float Kp=0.7,Ka=5,Kb=-2;
+    while(abs(x)<abs(x2)-1 || abs(y)<abs(y2)-1 || teta<=(phi2-0.05) || teta>=(phi2+0.05)) {// Condição de paragem
+        // Controlo linear
+        v=Kp*(sqrt(((x2-x)*(x2-x)+(y2-y)*(y2-y))));
+        
+        alfa=-teta+atan2(y2-y,x2-x);
+        
+        if(abs(v)<1){ 
+            alfa=0;
+            a=0;
+            b=0;
+        }
+        // Verifica se o alpha pertence ao limite entre [-pi/2; pi/2], se não adiciona/remove pi e inverte a velocidade
+        if(alfa<-pi/2){
+            alfa=alfa+pi;
+            v=-v;
+        }
+        else if(alfa>pi/2){
+            alfa=alfa-pi;
+            v=-v;
+        }
+        
+        beta=-teta-alfa+phi2;
+        w=Ka*alfa+Kb*beta;
+        
+        if(alfa==0){
+             w=w+abs(w)/w*4;
+             Kb=3;
+        }
+
+        motion();
+        setSpeeds(Wee+a*abs(v)/v,Wdd+b*abs(v)/v);
+
+        //PC.printf("v=%f w=%f alfa=%f beta=%f teta=%f phi2=%f x=%f y=%f\n", v,w,alfa,beta,teta,phi2,x,y);
+        PC.printf("%f %f\n", x,y);
+        }
+        setSpeeds(0,0); // A condição de paragem verifica-se e para-se o robo
+    }
+}
+
+
+/////////////////////////////////
+// Movimento segundo uma linha //
+/////////////////////////////////
+void to_line(float a,float b,float c)
+{
+    float d=0,alfad=0,phi1=0,alfah=0;
+    float Kd=0.45,Kh=15;
+    while(1){
+        while((abs(x) < 200)&&(abs(y)<200)) {
+            v=100;
+            d=(a*x+b*y+c)/sqrt(a*a+b*b);
+
+            //Controlo proporcional que roda a plataforma na direção da linha
+            alfad=(-Kd)*d;
+            if (abs(alfad)<0.3) alfad=alfad*3;
+            phi1=atan2(-a,b);
+            
+            //Controlo proporcional que ajusta o ângulo de direcionamento
+            alfah=Kh*(phi1-teta);
+            
+            w=alfad+alfah;
+            
+            if(w > 12) w = 12;
+            else if(w<-12) w = -12;
+
+            motion();
+            setSpeeds(Wee,Wdd);
+            //PC.printf("v=%f w=%f alfad=%f alfah=%f teta=%f x=%f y=%f\n", v,w,alfad,alfah,teta,x,y);
+            PC.printf("%f %f\n", x,y);
+        }
+        setSpeeds(0,0);
+    }
+}
+
+
+/////////////////////////////
+// Movimento para um ponto //
+/////////////////////////////
+void to_point(float x1,float y1)
+{
+    while(1) {
+        float phi1=0,aux=0;
+        float Kv=1.5,Ks=30;
+        while((abs(x)<abs(x1)-1)||(abs(y)<abs(y1)-1)||(abs(x)>abs(x1)+1)||(abs(y)>abs(y1)+1)) {
+            v=Kv*(sqrt(((x1-x)*(x1-x)+((y1-y)*(y1-y))))); //Controlo de velocidade -- Quanto mais próximo do ponto objetivo, menor vai ser a velocidade
+            
+            phi1=atan2((y1-y),(x1-x)); // Ângulo entre a posição final e a posição atual
+            
+            aux=phi1-teta;
+            //Verifica se a diferença dos angulos pertence ao limite entre [-pi;pi]
+            if(aux<-pi){
+                aux=aux+2*pi;
+            }
+            else if(aux>pi){
+                aux=aux-2*pi;
+            }
+            
+            //Controlo proporcional
+            w=Ks*(aux);
+            
+            if(w > 12) w = 12;
+            else if(w<-12) w = -12;
+
+            motion();
+            setSpeeds(Wee+28,Wdd+25);
+            //PC.printf("v=%f w=%f phi1=%f x=%f y=%f teta=%f\n", v,w,phi1,x,y,teta);
+            PC.printf("%f %f %f %f\n", x,y,teta, w);
+        }
+        setSpeeds(0,0);
+    }
+
+}
+
+///////////////
+// Odometria //
+///////////////
+void motion()
+{
+    getCountsAndReset();
+    De=((2*pi*r)*countsLeft)/1440;
+    Dd=((2*pi*r)*countsRight)/1440;
+    theta=(Dd-De)/Ldis;
+    
+    D=(De+Dd)/2;
+    
+    if(theta==0) {
+        x=x+D*cos(teta);
+        y=y+D*sin(teta);
+        teta=teta;
+    } else {
+        x = x + D*((sin(theta/2)/(theta/2))*cos(teta+theta/2));
+        y = y + D*((sin(theta/2)/(theta/2))*sin(teta+theta/2));
+        teta=teta+theta;
+    }
+    
+    //Limite entre [-2pi; 2pi]
+    if (teta>=(2*pi)) {
+        teta=teta-2*pi;
+    }
+    if (teta<=(-2*pi)) {
+        teta=teta+2*pi;
+    }
+
+    Wee=(v-(Ldis/2)*w);
+    Wdd=(v+(Ldis/2)*w);
+    //PC.printf("phi1=%f D=%f x=%f y=%f teta=%f\n", w,theta,x,y,teta);
+}
+
+void setSpeeds(int16_t leftSpeed, int16_t rightSpeed)
+{
+    char buffer[5];
+
+    buffer[0] = 0xA1;
+    memcpy(&buffer[1], &leftSpeed, sizeof(leftSpeed));
+    memcpy(&buffer[3], &rightSpeed, sizeof(rightSpeed));
+
+    i2c.write(addr8bit, buffer, 5); // 5 bytes
+}
+
+void setLeftSpeed(int16_t speed)
+{
+    char buffer[3];
+
+    buffer[0] = 0xA2;
+    memcpy(&buffer[1], &speed, sizeof(speed));
+
+    i2c.write(addr8bit, buffer, 3); // 3 bytes
+}
+
+void setRightSpeed(int16_t speed)
+{
+    char buffer[3];
+
+    buffer[0] = 0xA3;
+    memcpy(&buffer[1], &speed, sizeof(speed));
+
+    i2c.write(addr8bit, buffer, 3); // 3 bytes
+}
+
+void getCounts()
+{
+    char write_buffer[2];
+    char read_buffer[4];
+
+    write_buffer[0] = 0xA0;
+    i2c.write(addr8bit, write_buffer, 1);
+    wait_us(100);
+    i2c.read( addr8bit, read_buffer, 4);
+    countsLeft = (int16_t((read_buffer[0]<<8)|read_buffer[1]));
+    countsRight = (int16_t((read_buffer[2]<<8)|read_buffer[3]));
+}
+
+void getCountsAndReset()
+{
+    char write_buffer[2];
+    char read_buffer[4];
+
+    write_buffer[0] = 0xA4;
+    i2c.write(addr8bit, write_buffer, 1);
+    wait_us(100);
+    i2c.read( addr8bit, read_buffer, 4);
+    countsLeft = (int16_t((read_buffer[0]<<8)|read_buffer[1]));
+    countsRight = (int16_t((read_buffer[2]<<8)|read_buffer[3]));
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Robot.h	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,60 @@
+/** @file */
+#ifndef ROBOT_H_
+#define ROBOT_H_
+
+#include "mbed.h"
+
+extern int16_t countsLeft;
+extern int16_t countsRight;
+extern float De,Dd,T,pi,L,r,x,y,teta;
+
+/** \brief Sets the speed for both motors.
+ *
+ * \param leftSpeed A number from -300 to 300 representing the speed and
+ * direction of the left motor. Values of -300 or less result in full speed
+ * reverse, and values of 300 or more result in full speed forward.
+ * \param rightSpeed A number from -300 to 300 representing the speed and
+ * direction of the right motor. Values of -300 or less result in full speed
+ * reverse, and values of 300 or more result in full speed forward. */
+void setSpeeds(int16_t leftSpeed, int16_t rightSpeed);
+
+/** \brief Sets the speed for the left motor.
+ *
+ * \param speed A number from -300 to 300 representing the speed and
+ * direction of the left motor.  Values of -300 or less result in full speed
+ * reverse, and values of 300 or more result in full speed forward. */
+void setLeftSpeed(int16_t speed);
+
+/** \brief Sets the speed for the right motor.
+ *
+ * \param speed A number from -300 to 300 representing the speed and
+ * direction of the right motor. Values of -300 or less result in full speed
+ * reverse, and values of 300 or more result in full speed forward. */
+void setRightSpeed(int16_t speed);
+
+/*! Returns the number of counts that have been detected from the both
+ * encoders.  These counts start at 0.  Positive counts correspond to forward
+ * movement of the wheel of the Romi, while negative counts correspond
+ * to backwards movement.
+ *
+ * The count is returned as a signed 16-bit integer.  When the count goes
+ * over 32767, it will overflow down to -32768.  When the count goes below
+ * -32768, it will overflow up to 32767. */
+void getCounts();
+
+/*! This function is just like getCounts() except it also clears the
+ *  counts before returning.  If you call this frequently enough, you will
+ *  not have to worry about the count overflowing. */
+void getCountsAndReset();
+
+void to_line(float a,float b,float c);
+
+void motion();
+
+void pressed();
+
+void to_point(float x1,float y1);
+
+void to_pos(float x2, float y2, float phi2);
+
+#endif /* ROBOT_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,38 @@
+#include "mbed.h"
+#include "Robot.h"
+#include "Communication.h"
+
+Serial pc(SERIAL_TX, SERIAL_RX);
+InterruptIn button(USER_BUTTON);
+
+volatile bool mode=true;
+float x1=40,y1=-40;          // Posição inicial do robo
+float a1=1,b1=-2,c1=4;       // Reta ax + by + c = 0
+float x2=50,y2=50,phi2=pi/2; // Pose arbitrária
+
+void pressed()
+{
+    mode= !mode;
+}
+
+int main()
+{
+    pc.baud(9600);
+    button.fall(&pressed);
+
+    while(1) {
+        if (mode==true) {
+            setSpeeds(0,0);
+
+        } else {
+            setSpeeds(0,0); 
+            
+            motion();
+            wait(1);
+            
+            //to_point(x1,y1);
+            //to_line(a1,b1,c1);
+            to_pos(x2,y2,phi2);
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Mar 13 23:04:14 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file