Sam

Files at this revision

API Documentation at this revision

Comitter:
s0313045
Date:
Sun Sep 13 04:30:54 2020 +0000
Parent:
1:58d1caed28d4
Commit message:
by Sam

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
main_front_is_two_wheel.txt Show annotated file Show diff for this revision Revisions of this file
main_rotate_stable_wtf.txt Show diff for this revision Revisions of this file
main_stable.txt Show diff for this revision Revisions of this file
main_stable2_still_on9.txt Show diff for this revision Revisions of this file
main_stable_ex_1_2018_10_25.txt Show diff for this revision Revisions of this file
--- a/main.cpp	Thu Oct 25 12:14:32 2018 +0000
+++ b/main.cpp	Sun Sep 13 04:30:54 2020 +0000
@@ -1,4 +1,13 @@
 #include "mbed.h"
+
+#include "ros.h"
+#include <nav_msgs/Odometry.h>
+#include <geometry_msgs/Twist.h>
+#include <geometry_msgs/Quaternion.h>
+#include <geometry_msgs/TransformStamped.h>
+#include <tf/tf.h>
+#include <tf/transform_broadcaster.h>
+
 #include "actiondrv.h"
 
 #include "millis.h"
@@ -18,7 +27,7 @@
 ///////////////////////////
 //Serial Action(D8,D2 ); // tx, rx
 Serial Action(PB_6,  PB_7 );
-Serial pc(USBTX, USBRX);
+//Serial pc(USBTX, USBRX);
 
 
 
@@ -41,13 +50,13 @@
 bool newDataArrived=false;
 
 char buffer[8];
-/////////////////////////
+
 
 //Serial pc(USBTX, USBRX);
 char counter = 0;
-actionDrv action1(1);
-actionDrv action2(2);
-actionDrv action3(3);
+actionDrv action1(3); //1
+actionDrv action2(1); //2
+actionDrv action3(2); //3
 
 
 int motor1 = 0;
@@ -64,6 +73,10 @@
 Ticker motor_updater;
 
 Ticker odom_updater;
+
+Ticker ros_updater;
+
+
 ////////////////////////////////////
 float now_x=0;
 float now_y=0;
@@ -85,36 +98,16 @@
 
 /////////////////////////////////////
 const float RATE = 0.18;
-
-///////////////////////////////////////
-int point_counter=0;
-
-struct point_info
-{
-   float required_x;
-   float required_y;
-   float required_w;
-   float required_tolerance_x;
-   float required_tolerance_y;
-   float required_tolerance_w;
-   float required_speed_max_x;
-   float required_speed_max_y;
-   float required_speed_max_w;
-};
-
-struct point_info points[100];
-
-
-
+//////////////////////////
 
 ///////////////////////////
-float encoder_2_global_angle = 30;         //encoder coordinate system + 30 degree    =>  global coordinate system
+float encoder_2_global_angle = -90;         //encoder coordinate system + 30 degree    =>  global coordinate system
 //float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
 //float encoder_2_global_y     =   -0.235;     //encoder to center distance  in y   (tung)
 
 
-float encoder_2_global_x     = 0.125;//0.125;// -0.13 ;    //encoder to center distance  in x   (tung)
-float encoder_2_global_y     = 0.37; //0.35;     //encoder to center distance  in y   (tung)
+float encoder_2_global_x     = 0.33;//0.125;    //encoder to center distance  in x   (tung)
+float encoder_2_global_y     = 0.24;//0.37;    //encoder to center distance  in y   (tung)
 ////////////////////TUNG////////////////
 
 
@@ -132,8 +125,8 @@
 float encoder_to_center = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );
 
 //#########################//
-float encoder2local_angle = 30 *pi/float(180);
-float encoder_position_angle =( ( 180 + 18.666914)  ) / float(180) * pi ;   //90 +  angle to encoder location
+float encoder2local_angle = -90 *pi/float(180);
+float encoder_position_angle =( ( 360-36.02737)  ) / float(180) * pi ;   //90 +  angle to encoder location
 float r = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );   //encoder to center radius
 
 
@@ -154,11 +147,11 @@
     float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
     
     
-   // transformed_real_now_x = tx - x_tbias   - startup_offset_x_encoder;
-   // transformed_real_now_y = ty - y_tbias   - startup_offset_y_encoder;
+   transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder; //-
+   transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
     
-    transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder;
-    transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
+    //transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder;  //+
+    //transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
     
     
     transformed_real_now_w=   _A *pi/float(180)                                                                        -  startup_offset_w_encoder;
@@ -198,11 +191,11 @@
     float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
     
     
-  //  startup_offset_x_encoder = tx - x_tbias ;
-  //  startup_offset_y_encoder = ty - y_tbias ;
+    startup_offset_x_encoder = tx + y_tbias ;  //-
+    startup_offset_y_encoder = ty - x_tbias ;
     
-    startup_offset_x_encoder = tx + y_tbias ;
-    startup_offset_y_encoder = ty - x_tbias ;
+   //startup_offset_x_encoder = tx + y_tbias ;
+   //startup_offset_y_encoder = ty - x_tbias ;  //+
     
     
     startup_offset_w_encoder =  _A *pi/float(180);    //degree 2 rad
@@ -210,12 +203,6 @@
     
 }
 
-
-
-
-
-
-
 void ActionEncoder_init()
 {
     count=0;
@@ -300,82 +287,37 @@
     return false;
 }
 
-bool updated()
-{
-    if (done) {
-        done=false;
-        return true;
-    } else {
-        return false;
-    }
 
-}
 
-float getXangle()
-{
-    return xangle;
-}
 
-float getYangle()
-{
-    return yangle;
-}
-
-float getZangle()
+//void inverse(float global_x_vel, float global_y_vel, float w_vel) const std_msgs::UInt16& cmd_msg
+void inverse(const geometry_msgs::Twist& cmd_vel)  
 {
-    return zangle;
-}
-
-float getXpos()
-{
-    return pos_x;
-}
-
-float getYpos()
-{
-    return pos_y;
+    float global_vel_x   =  cmd_vel.linear.x;
+    float global_vel_y   =  cmd_vel.linear.y;
+    float w_vel          =  cmd_vel.angular.z;
+    
+    float local_x_vel = global_vel_x * cos( -transformed_real_now_w  )  -  global_vel_y * sin( -transformed_real_now_w ); 
+    float local_y_vel = global_vel_x * sin( -transformed_real_now_w  )  +  global_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
+  
+    motor1  =  int(   (    (-1) * sin(pi_div_3) * local_x_vel   +  cos(pi_div_3) * local_y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
+    motor2  =  int(   (    (-1) *  local_y_vel + d * w_vel                                                      )  * 60 / (wheelR * 2 * pi)  * gear   ); 
+    motor3  =  int(   (           sin(pi_div_3) * local_x_vel   +  cos(pi_div_3) * local_y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
+    
 }
 
-float getAngleSpeed()
-{
-    return angleSpeed;
-}
-
-bool isAlive()
-{
-    if ((millis()-LastRead)<100) {
-        return true;
-    } else {
-        return false;
-    }
-}
+/////////////////////////
+ros::NodeHandle nh;
+ros::Subscriber<geometry_msgs::Twist> sub("cmd_vel", &inverse );
 
-bool newDataAvailable()
-{
-    if (newDataArrived) {
-        newDataArrived=false;
-        return true;
-    } else return false;
-}
-
-char* reset()
-{
-    return "ACT0";
-}
-
-char* calibrate()
-{
-    return "ACTR";
-}
+nav_msgs::Odometry odom;
+geometry_msgs::TransformStamped odom_trans;
+ 
+ros::Publisher odom_publisher("odom", &odom);
+tf::TransformBroadcaster odom_broadcaster;
 
 
-void inverse(float x_vel, float y_vel, float w_vel)
-{
-    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
-    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    
-}
+/////////////////////////
 
 
 
@@ -387,111 +329,69 @@
     wait(0.005);
 }
 
+void ros_update()
+{
+
+odom_publisher.publish( &odom );
+odom_broadcaster.sendTransform(odom_trans);
+
+
+wait(0.005);
+nh.spinOnce();
+}
+
+
 void odom_update()
 {
-
-   
     calculatePos(now_x,now_y,now_w);
     
-    
-    /*sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    pc.printf("\r\n");
-    */
-    
-    
-    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
-    {
-        point_counter+=1;
+    //geometry_msgs::Quaternion odom_quat = createQuaternionMsg(transformed_real_now_w );
+    geometry_msgs::Quaternion odom_quat = tf::createQuaternionFromYaw(transformed_real_now_w);  // *57.2957795
 
-       tolerance_x = points[point_counter].required_tolerance_x;
-       tolerance_y = points[point_counter].required_tolerance_x;
-       tolerance_w = points[point_counter].required_tolerance_x;
-       
-       target_x    = points[point_counter].required_x                    ; //+    startup_offset_x_encoder;
-       target_y    = points[point_counter].required_y                    ; //+    startup_offset_y_encoder;
-       target_w    = points[point_counter].required_w  *pi/float(180);       ;//-    startup_offset_w_encoder;
-       
-       inverse( 0    ,     0         ,     0   );
-       return;
-     
-    }
-    
 
-  
-    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
-    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
-    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
-    
-    
-    
-    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
-    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
-    
-    /*
-    pc.printf("X: ");
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  Y: ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  W: ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    
-    pc.printf(" | Global: ");
-    sprintf(buffer, "%f", global_vel_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", global_vel_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", local_vel_w);
-    pc.printf(buffer);*/
-    
-    
-  
-    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
-    
-    /*
-    pc.printf(" | Motor: ");
-    sprintf(buffer, "%d", motor1);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor2);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor3);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-}
+    //first, we'll publish the transform over tf
+    odom_trans.header.stamp = nh.now();
+    odom_trans.header.frame_id = "odom";
+    odom_trans.child_frame_id = "base_link";
 
-int main() {
-    //while(1){
-////////////////////////////
-    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[1] = (point_info){.required_x = 0.5,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[2] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[3] = (point_info){.required_x = 0,  .required_y = 0.2, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[4] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[5] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[7] = (point_info){.required_x = 0,  .required_y = 0, .required_w = -90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[8] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    odom_trans.transform.translation.x = transformed_real_now_x ;
+    odom_trans.transform.translation.y = transformed_real_now_y ;
+    odom_trans.transform.translation.z = 0.0;
+    odom_trans.transform.rotation = odom_quat;
+
+    //send the transform
     
 
 
 
+    //next, we'll publish the odometry message over ROS
+    //nav_msgs::Odometry odom;
+    odom.header.stamp = nh.now();
+    odom.header.frame_id = "odom";
+    odom.child_frame_id = "base_link";
 
-////////////////////
-        
+    //set the position
+    odom.pose.pose.position.x = transformed_real_now_x;
+    odom.pose.pose.position.y = transformed_real_now_y ;
+    odom.pose.pose.position.z = 0.0;
+    odom.pose.pose.orientation = odom_quat;
+
+    //set the velocity
+    //odom.child_frame_id = "base_link";
+    //odom.twist.twist.linear.x = vx;
+    //odom.twist.twist.linear.y = vy;
+    //odom.twist.twist.angular.z = vth;
+
+    //publish the message    
+    //
+    
+            
+}
+    
+
+
+int main() {
+    
     millisStart();
     
     
@@ -499,6 +399,34 @@
     Action.baud(115200);
     Action.format(8,SerialBase::None,1); 
     ActionEncoder_init();
+    
+    nh.initNode();
+    odom_broadcaster.init(nh);
+    nh.advertise(odom_publisher);
+    nh.subscribe(sub);
+    
+    while (!nh.connected() )   {nh.spinOnce();}
+        odom_trans.header.stamp = nh.now();
+        odom_trans.header.frame_id = "odom";
+        odom_trans.child_frame_id = "base_link";
+    
+        odom_trans.transform.translation.x = 0.0;
+        odom_trans.transform.translation.y = 0.0 ;
+        odom_trans.transform.translation.z = 0.0;
+        odom_trans.transform.rotation = tf::createQuaternionFromYaw(0);
+        
+        odom.header.stamp = nh.now();
+        odom.header.frame_id = "odom";
+        odom.child_frame_id = "base_link";
+    
+        //set the position
+        odom.pose.pose.position.x = transformed_real_now_x;
+        odom.pose.pose.position.y = transformed_real_now_y ;
+        odom.pose.pose.position.z = 0.0;
+        odom.pose.pose.orientation = tf::createQuaternionFromYaw(0);;
+        
+    ros_updater.attach(&ros_update, 0.3);
+    
     while(1) 
     {
         if (Action.readable())
@@ -518,10 +446,6 @@
         }
     }    //start first to take offset from encoder... in case already moved
     
- 
-   target_x    = points[0].required_x;  //  +  startup_offset_x_encoder;
-   target_y    = points[0].required_y;  //  +  startup_offset_y_encoder;
-   target_w    = points[0].required_w *pi/float(180);   // -  startup_offset_w_encoder;
     
     
     for( int a = 1; a < 2; a++ ){
@@ -541,6 +465,9 @@
           
     motor_updater.attach(&motor_update, RATE);  
     //odom_updater.attach(&odom_update, RATE);
+    ros_updater.attach(&ros_update, 0.5);
+    
+
     
         
     while(1) 
@@ -554,38 +481,5 @@
         
     }
 
- 
-        
-/*
-        while (Action.readable()==1 ) 
-        {
-            char c = Action.getc();   
-            readEncoder(c);
-           
-        }
-*/
-    
-    
-/*
-    while(1)
-    {
-         
-         inverse(0.2,0,0);
-         wait(1);
-         inverse(-0.2,0,0);
-         wait(1);
-         
-         inverse(0,0,0.25);
-         wait(1);
-         inverse(0,0,-0.25);
-         wait(1);
-         
-    }
-    
-*/
-         
-
-    
-
        
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main_front_is_two_wheel.txt	Sun Sep 13 04:30:54 2020 +0000
@@ -0,0 +1,533 @@
+#include "mbed.h"
+#include "actiondrv.h"
+
+#include "millis.h"
+
+/*
+ * ActionEncoder.cpp
+ *
+ *  Created on: 7 Mar 2018
+ *      Author: tung
+ */
+
+#include "ActionEncoder.hpp"
+#include "Timer.h"
+
+
+
+///////////////////////////
+//Serial Action(D8,D2 ); // tx, rx
+Serial Action(PB_6,  PB_7 );
+Serial pc(USBTX, USBRX);
+
+
+
+union {
+    uint8_t data[24];
+    float val[6];
+} posture;
+int count=0;
+int i=0;
+int done=0;
+float xangle=0;
+float yangle=0;
+float zangle=0;
+float d_angle=0;
+float pos_x=0;
+float pos_y=0;
+float angleSpeed=0;
+float temp_zangle=0;
+int   LastRead=0;
+bool newDataArrived=false;
+
+char buffer[8];
+/////////////////////////
+
+//Serial pc(USBTX, USBRX);
+char counter = 0;
+actionDrv action1(3); //1
+actionDrv action2(1);  //2
+actionDrv action3(2); //3
+
+
+int motor1 = 0;
+int motor2 = 0;
+int motor3 = 0;
+int motor4 = 0;
+
+float pi = 3.14159265;
+double pi_div_3 = 1.04719755;
+float d = 0.525;//0.43;
+float wheelR = 0.0508; //4 inch wheel
+float gear = 10;
+
+Ticker motor_updater;
+
+Ticker odom_updater;
+////////////////////////////////////
+float now_x=0;
+float now_y=0;
+float now_w=0;
+
+float target_x=0;
+float target_y=0;
+float target_w=0;
+
+float tolerance_x=0.02;
+float tolerance_y=0.02;
+float tolerance_w=0.01;
+
+float speed_max_x=1;
+float speed_max_y=1;
+float speed_max_w=1;
+
+long odom_last_read= millis();
+
+/////////////////////////////////////
+const float RATE = 0.18;
+
+///////////////////////////////////////
+int point_counter=0;
+
+struct point_info
+{
+   float required_x;
+   float required_y;
+   float required_w;
+   float required_tolerance_x;
+   float required_tolerance_y;
+   float required_tolerance_w;
+   float required_speed_max_x;
+   float required_speed_max_y;
+   float required_speed_max_w;
+};
+
+struct point_info points[100];
+
+
+
+
+///////////////////////////
+float encoder_2_global_angle = -90;         //encoder coordinate system + 30 degree    =>  global coordinate system
+//float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
+//float encoder_2_global_y     =   -0.235;     //encoder to center distance  in y   (tung)
+
+
+float encoder_2_global_x     = 0.33;//0.125;    //encoder to center distance  in x   (tung)
+float encoder_2_global_y     = 0.24;//0.37;    //encoder to center distance  in y   (tung)
+////////////////////TUNG////////////////
+
+
+float transformed_real_now_x=0;
+float transformed_real_now_y=0;
+float transformed_real_now_w=0;
+
+
+float startup_offset_x_encoder =0;
+float startup_offset_y_encoder =0;
+float startup_offset_w_encoder=0;
+
+
+
+float encoder_to_center = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );
+
+//#########################//
+float encoder2local_angle = -90 *pi/float(180);
+float encoder_position_angle =( ( 360-36.02737)  ) / float(180) * pi ;   //90 +  angle to encoder location
+float r = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );   //encoder to center radius
+
+
+void calculatePos(float _X,float _Y,float _A)
+{
+    float zangle  =  _A-   360 * int(_A / 360);
+    float zrangle =  zangle *pi/float(180);    //degree 2 rad
+    
+    float tx = ( ( _X / float(1000) ) * cos( -encoder2local_angle) )  -  (  ( _Y / float(1000) )   *  sin( -encoder2local_angle) );
+    float ty = ( ( _X / float(1000) ) * sin( -encoder2local_angle) )  +  (  ( _Y / float(1000) )   *  cos( -encoder2local_angle) );
+    
+    float s  = copysign( sqrt(  2*( r*r )  -  2*(r*r)*cos(zrangle)  )    , zrangle );
+    
+    float x_bias = s * cos( zrangle / 2 );
+    float y_bias = s * sin( zrangle / 2 );
+    
+    float x_tbias = ( x_bias ) * ( cos( encoder_position_angle) )  - ( y_bias ) * ( sin( encoder_position_angle ) )    ;
+    float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
+    
+    
+   transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder; //-
+   transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
+    
+    //transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder;  //+
+    //transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
+    
+    
+    transformed_real_now_w=   _A *pi/float(180)                                                                        -  startup_offset_w_encoder;
+    
+    
+}
+
+
+
+
+
+///////////////////////
+
+
+
+float x_PID_P = 0.5;
+float y_PID_P = 0.5;
+float w_PID_P = 1;
+
+#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
+
+//////////////////////////////
+void start_calculatePos(float _X,float _Y,float _A)
+{
+    float zangle  =  _A-   360 * int(_A / 360);
+    float zrangle =  zangle *pi/float(180);    //degree 2 rad
+    
+    float tx = ( ( _X / float(1000) ) * cos( -encoder2local_angle) )  -  (  ( _Y / float(1000) )   *  sin( -encoder2local_angle) );
+    float ty = ( ( _X / float(1000) ) * sin( -encoder2local_angle) )  +  (  ( _Y / float(1000) )   *  cos( -encoder2local_angle) );
+    
+    float s  = copysign( sqrt(  2*( r*r )  -  2*(r*r)*cos(zrangle)  )    , zrangle );
+    
+    float x_bias = s * cos( zrangle / 2 );
+    float y_bias = s * sin( zrangle / 2 );
+    
+    float x_tbias = ( x_bias ) * ( cos( encoder_position_angle) )  - ( y_bias ) * ( sin( encoder_position_angle ) )    ;
+    float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
+    
+    
+    startup_offset_x_encoder = tx + y_tbias ;  //-
+    startup_offset_y_encoder = ty - x_tbias ;
+    
+   //startup_offset_x_encoder = tx + y_tbias ;
+   //startup_offset_y_encoder = ty - x_tbias ;  //+
+    
+    
+    startup_offset_w_encoder =  _A *pi/float(180);    //degree 2 rad
+    
+    
+}
+
+
+
+
+
+
+
+void ActionEncoder_init()
+{
+    count=0;
+    i=0;
+    done=0;
+    xangle=0;
+    yangle=0;
+    zangle=0;
+    d_angle=0;
+    pos_x=0;
+    pos_y=0;
+    angleSpeed=0;
+    temp_zangle=0;
+    LastRead=0;
+    newDataArrived=false;
+
+}
+
+bool readEncoder(char c)
+{
+    //sprintf(buffer,"%02X",c);
+    //sprintf(buffer,"%X",c);
+    //pc.printf(buffer);
+    //pc.printf("\r\n");
+    
+    //sprintf(buffer,"%d",count);
+    //pc.printf(buffer);
+    //pc.printf("\r\n");
+    switch(count) {
+        case 0:
+            if (c==0x0d) count++;
+            else count=0;
+            break;
+        case 1:
+            if(c==0x0a) {
+                i=0;
+                count++;
+            } else if(c==0x0d) {}
+            else count=0;
+            break;
+        case 2:
+            posture.data[i]=c;
+            i++;
+            if(i>=24) {
+                i=0;
+                count++;
+            }
+            break;
+        case 3:
+            if(c==0x0a)count++;
+            else count=0;
+            break;
+        case 4:
+            if(c==0x0d) {
+                d_angle=posture.val[0]-temp_zangle;
+                if (d_angle<-180) {
+                    d_angle=d_angle+360;
+                } else if (d_angle>180) {
+                    d_angle=d_angle-360;
+                }
+                
+                now_w+=d_angle;
+                temp_zangle=posture.val[0];
+                //xangle=posture.val[1];
+                //yangle=posture.val[2];
+                now_x=posture.val[3];
+                now_y=posture.val[4];
+                //angleSpeed=posture.val[5];
+                newDataArrived=true;
+                
+            }
+            count=0;
+            done=1;
+            LastRead=millis();
+            return true;
+            //break;
+        default:
+            count=0;
+            break;
+    }
+    
+    return false;
+}
+
+
+
+void inverse(float x_vel, float y_vel, float w_vel)
+{
+    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
+    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
+    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
+    
+}
+
+
+
+void motor_update()
+{
+    action1.SetVelocity_mod(motor1  * -1 );
+    action2.SetVelocity_mod(motor2  * -1 );
+    action3.SetVelocity_mod(motor3  * -1 );
+    wait(0.005);
+}
+
+void odom_update()
+{
+
+   
+    calculatePos(now_x,now_y,now_w);
+    
+    
+    /*sprintf(buffer, "%f", transformed_real_now_x);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%f", transformed_real_now_y);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%f", transformed_real_now_w);
+    pc.printf(buffer);
+    pc.printf("\r\n");
+    */
+    
+    
+    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
+    {
+        point_counter+=1;
+
+       tolerance_x = points[point_counter].required_tolerance_x;
+       tolerance_y = points[point_counter].required_tolerance_x;
+       tolerance_w = points[point_counter].required_tolerance_x;
+       
+       target_x    = points[point_counter].required_x                    ; //+    startup_offset_x_encoder;
+       target_y    = points[point_counter].required_y                    ; //+    startup_offset_y_encoder;
+       target_w    = points[point_counter].required_w  *pi/float(180);       ;//-    startup_offset_w_encoder;
+       
+       inverse( 0    ,     0         ,     0   );
+       return;
+     
+    }
+    
+
+  
+    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
+    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
+    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
+    
+    
+    
+    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
+    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
+    
+    /*
+    pc.printf("X: ");
+    sprintf(buffer, "%f", transformed_real_now_x);
+    pc.printf(buffer);
+    pc.printf("  Y: ");
+    sprintf(buffer, "%f", transformed_real_now_y);
+    pc.printf(buffer);
+    pc.printf("  W: ");
+    sprintf(buffer, "%f", transformed_real_now_w);
+    pc.printf(buffer);
+    
+    pc.printf(" | Global: ");
+    sprintf(buffer, "%f", global_vel_x);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%f", global_vel_y);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%f", local_vel_w);
+    pc.printf(buffer);*/
+    
+    
+  
+    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
+    
+    /*
+    pc.printf(" | Motor: ");
+    sprintf(buffer, "%d", motor1);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%d", motor2);
+    pc.printf(buffer);
+    pc.printf("  ");
+    sprintf(buffer, "%d", motor3);
+    pc.printf(buffer);
+    pc.printf("\r\n");*/
+    
+}
+
+int main() {
+    //while(1){
+////////////////////////////
+
+
+    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[1] = (point_info){.required_x = 0.2,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[2] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[3] = (point_info){.required_x = 0,  .required_y = 0.2, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[4] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[5] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[7] = (point_info){.required_x = 0,  .required_y = 0, .required_w = -90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[8] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    
+/*
+    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w =  0,   .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[1] = (point_info){.required_x = 0.5,.required_y = 0, .required_w =  0,   .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[2] = (point_info){.required_x = 0.5,.required_y = 0.5, .required_w = 45, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[3] = (point_info){.required_x = 1,  .required_y = 0.5, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[4] = (point_info){.required_x = 0.5,.required_y = 0.5, .required_w = 45, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[5] = (point_info){.required_x = 0.5,.required_y = 0, .required_w =  0,  .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
+*/
+
+
+////////////////////
+        
+    millisStart();
+    
+    
+        
+    Action.baud(115200);
+    Action.format(8,SerialBase::None,1); 
+    ActionEncoder_init();
+    while(1) 
+    {
+        if (Action.readable())
+        {
+            char c = Action.getc();
+            if (readEncoder(c))
+            {
+                //startup_offset_x_encoder = now_x/1000;
+                //startup_offset_y_encoder = now_y/1000;
+                //startup_offset_w_encoder = now_w/float(180)*pi;
+                
+                start_calculatePos(  (now_x),(now_y), now_w  );   //global
+                break;
+            
+            }
+            
+        }
+    }    //start first to take offset from encoder... in case already moved
+    
+ 
+   target_x    = points[0].required_x;  //  +  startup_offset_x_encoder;
+   target_y    = points[0].required_y;  //  +  startup_offset_y_encoder;
+   target_w    = points[0].required_w *pi/float(180);   // -  startup_offset_w_encoder;
+    
+    
+    for( int a = 1; a < 2; a++ ){
+      action1.Enable();
+      action2.Enable();
+      action3.Enable();
+      wait(0.1);
+      action1.SetOperationalMode();
+      action2.SetOperationalMode();
+      action3.SetOperationalMode();
+      wait(0.1);
+      action1.Configvelocity(100000, 100000);
+      action2.Configvelocity(100000, 100000);
+      action3.Configvelocity(100000, 100000);  
+      wait(0.1);
+   }
+          
+    motor_updater.attach(&motor_update, RATE);  
+    //odom_updater.attach(&odom_update, RATE);
+    
+        
+    while(1) 
+    {
+        if (Action.readable())
+        {
+            //pc.putc('a');
+            char c = Action.getc();
+            if(readEncoder(c)) odom_update();
+        }
+        
+    }
+
+ 
+        
+/*
+        while (Action.readable()==1 ) 
+        {
+            char c = Action.getc();   
+            readEncoder(c);
+           
+        }
+*/
+    
+    
+/*
+    while(1)
+    {
+         
+         inverse(0.2,0,0);
+         wait(1);
+         inverse(-0.2,0,0);
+         wait(1);
+         
+         inverse(0,0,0.25);
+         wait(1);
+         inverse(0,0,-0.25);
+         wait(1);
+         
+    }
+    
+*/
+         
+
+    
+
+       
+}
--- a/main_rotate_stable_wtf.txt	Thu Oct 25 12:14:32 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,553 +0,0 @@
-#include "mbed.h"
-#include "actiondrv.h"
-
-#include "millis.h"
-
-/*
- * ActionEncoder.cpp
- *
- *  Created on: 7 Mar 2018
- *      Author: tung
- */
-
-#include "ActionEncoder.hpp"
-#include "Timer.h"
-
-
-
-///////////////////////////
-//Serial Action(D8,D2 ); // tx, rx
-Serial Action(PB_6,  PB_7 );
-Serial pc(USBTX, USBRX);
-
-
-
-union {
-    uint8_t data[24];
-    float val[6];
-} posture;
-int count=0;
-int i=0;
-int done=0;
-float xangle=0;
-float yangle=0;
-float zangle=0;
-float d_angle=0;
-float pos_x=0;
-float pos_y=0;
-float angleSpeed=0;
-float temp_zangle=0;
-int   LastRead=0;
-bool newDataArrived=false;
-
-char buffer[8];
-/////////////////////////
-
-//Serial pc(USBTX, USBRX);
-char counter = 0;
-actionDrv action1(1);
-actionDrv action2(2);
-actionDrv action3(3);
-
-
-int motor1 = 0;
-int motor2 = 0;
-int motor3 = 0;
-int motor4 = 0;
-
-float pi = 3.14159265;
-double pi_div_3 = 1.04719755;
-float d = 0.525;//0.43;
-float wheelR = 0.0508; //4 inch wheel
-float gear = 10;
-
-Ticker motor_updater;
-
-Ticker odom_updater;
-////////////////////////////////////
-float now_x=0;
-float now_y=0;
-float now_w=0;
-
-float target_x=0;
-float target_y=0;
-float target_w=0;
-
-float tolerance_x=0.02;
-float tolerance_y=0.02;
-float tolerance_w=0.01;
-
-float speed_max_x=1;
-float speed_max_y=1;
-float speed_max_w=1;
-
-long odom_last_read= millis();
-
-/////////////////////////////////////
-const float RATE = 0.18;
-
-///////////////////////////////////////
-int point_counter=0;
-
-struct point_info
-{
-   float required_x;
-   float required_y;
-   float required_w;
-   float required_tolerance_x;
-   float required_tolerance_y;
-   float required_tolerance_w;
-   float required_speed_max_x;
-   float required_speed_max_y;
-   float required_speed_max_w;
-};
-
-struct point_info points[100];
-
-
-
-
-///////////////////////////
-float encoder_2_global_angle = 30;         //encoder coordinate system + 30 degree    =>  global coordinate system
-//float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
-//float encoder_2_global_y     =   -0.235;     //encoder to center distance  in y   (tung)
-
-
-float encoder_2_global_x     = 0.125;// -0.13 ;    //encoder to center distance  in x   (tung)
-float encoder_2_global_y     =  0.37; //0.35;     //encoder to center distance  in y   (tung)
-////////////////////TUNG////////////////
-
-float    Xshift=  encoder_2_global_x;
-float    Yshift=  encoder_2_global_y;
-float    offsetX = -Yshift;
-float    offsetY = Xshift;
-
-float Ashift  =   -encoder_2_global_angle*pi/float(180);
-float offsetA =   -encoder_2_global_angle;
-
-float transformed_real_now_x=0;
-float transformed_real_now_y=0;
-float transformed_real_now_w=0;
-
-
-float startup_offset_x_encoder =0;
-float startup_offset_y_encoder =0;
-float startup_offset_w_encoder=0;
-
-void calculatePos(float _X,float _Y,float _A)
-{
-    float radAng=_A/float(180)*pi;
-
-    float rotatedPosX=_X*cos(Ashift)+_Y*sin(Ashift);
-    float rotatedPosY=-_X*sin(Ashift)+_Y*cos(Ashift);
-    transformed_real_now_x=(rotatedPosY/float(1000)+Xshift*sin(radAng)+Yshift*cos(radAng))+offsetX        + startup_offset_x_encoder;
-    transformed_real_now_y=(rotatedPosX/float(1000)+Xshift*cos(radAng)-Yshift*sin(radAng))*(-1)+offsetY   + startup_offset_y_encoder;
-    //transformed_real_now_w=_A;   //
-    transformed_real_now_w=radAng                                                                         - startup_offset_w_encoder;
-}
-
-
-
-
-
-
-
-
-
-///////////////////////
-
-
-
-float x_PID_P = 0.5;
-float y_PID_P = 0.5;
-float w_PID_P = 1;
-
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-
-//////////////////////////////
-void start_calculatePos(float _X,float _Y,float _A)
-{
-    float radAng=_A/float(180)*pi;
-    float rotatedPosX=_X*cos(Ashift)+_Y*sin(Ashift);
-    float rotatedPosY=-_X*sin(Ashift)+_Y*cos(Ashift);
-    startup_offset_x_encoder  =  (rotatedPosY/float(1000)+Xshift*sin(radAng)+Yshift*cos(radAng))+offsetX;
-    startup_offset_y_encoder  =  (rotatedPosX/float(1000)+Xshift*cos(radAng)-Yshift*sin(radAng))*(-1)+offsetY;
-    //transformed_real_now_w=_A;   //
-    startup_offset_w_encoder=radAng;
-}
-
-
-
-
-
-void ActionEncoder_init()
-{
-    count=0;
-    i=0;
-    done=0;
-    xangle=0;
-    yangle=0;
-    zangle=0;
-    d_angle=0;
-    pos_x=0;
-    pos_y=0;
-    angleSpeed=0;
-    temp_zangle=0;
-    LastRead=0;
-    newDataArrived=false;
-
-}
-
-bool readEncoder(char c)
-{
-    //sprintf(buffer,"%02X",c);
-    //sprintf(buffer,"%X",c);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    
-    //sprintf(buffer,"%d",count);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    switch(count) {
-        case 0:
-            if (c==0x0d) count++;
-            else count=0;
-            break;
-        case 1:
-            if(c==0x0a) {
-                i=0;
-                count++;
-            } else if(c==0x0d) {}
-            else count=0;
-            break;
-        case 2:
-            posture.data[i]=c;
-            i++;
-            if(i>=24) {
-                i=0;
-                count++;
-            }
-            break;
-        case 3:
-            if(c==0x0a)count++;
-            else count=0;
-            break;
-        case 4:
-            if(c==0x0d) {
-                d_angle=posture.val[0]-temp_zangle;
-                if (d_angle<-180) {
-                    d_angle=d_angle+360;
-                } else if (d_angle>180) {
-                    d_angle=d_angle-360;
-                }
-                
-                now_w+=d_angle;
-                temp_zangle=posture.val[0];
-                //xangle=posture.val[1];
-                //yangle=posture.val[2];
-                now_x=posture.val[3];
-                now_y=posture.val[4];
-                //angleSpeed=posture.val[5];
-                newDataArrived=true;
-                
-            }
-            count=0;
-            done=1;
-            LastRead=millis();
-            return true;
-            //break;
-        default:
-            count=0;
-            break;
-    }
-    
-    return false;
-}
-
-bool updated()
-{
-    if (done) {
-        done=false;
-        return true;
-    } else {
-        return false;
-    }
-
-}
-
-float getXangle()
-{
-    return xangle;
-}
-
-float getYangle()
-{
-    return yangle;
-}
-
-float getZangle()
-{
-    return zangle;
-}
-
-float getXpos()
-{
-    return pos_x;
-}
-
-float getYpos()
-{
-    return pos_y;
-}
-
-float getAngleSpeed()
-{
-    return angleSpeed;
-}
-
-bool isAlive()
-{
-    if ((millis()-LastRead)<100) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-bool newDataAvailable()
-{
-    if (newDataArrived) {
-        newDataArrived=false;
-        return true;
-    } else return false;
-}
-
-char* reset()
-{
-    return "ACT0";
-}
-
-char* calibrate()
-{
-    return "ACTR";
-}
-
-
-void inverse(float x_vel, float y_vel, float w_vel)
-{
-    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
-    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    
-}
-
-
-
-void motor_update()
-{
-    action1.SetVelocity_mod(motor1  * -1 );
-    action2.SetVelocity_mod(motor2  * -1 );
-    action3.SetVelocity_mod(motor3  * -1 );
-    wait(0.005);
-}
-
-void odom_update()
-{
-
-   
-    calculatePos(now_x,now_y,now_w);
-    
-    
-    /*sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    pc.printf("\r\n");
-    */
-    
-    
-    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
-    {
-        point_counter+=1;
-
-       tolerance_x = points[point_counter].required_tolerance_x;
-       tolerance_y = points[point_counter].required_tolerance_x;
-       tolerance_w = points[point_counter].required_tolerance_x;
-       
-       target_x    = points[point_counter].required_x                    ; //+    startup_offset_x_encoder;
-       target_y    = points[point_counter].required_y                    ; //+    startup_offset_y_encoder;
-       target_w    = points[point_counter].required_w  /float(180)*pi    ;//-    startup_offset_w_encoder;
-       
-       inverse( 0    ,     0         ,     0   );
-       return;
-     
-    }
-    
-
-  
-    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
-    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
-    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
-    
-    
-    
-    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
-    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
-    
-    /*
-    pc.printf("X: ");
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  Y: ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  W: ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    
-    pc.printf(" | Global: ");
-    sprintf(buffer, "%f", global_vel_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", global_vel_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", local_vel_w);
-    pc.printf(buffer);*/
-    
-    
-  
-    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
-    
-    /*
-    pc.printf(" | Motor: ");
-    sprintf(buffer, "%d", motor1);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor2);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor3);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-}
-
-int main() {
-    //while(1){
-////////////////////////////
-    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[1] = (point_info){.required_x = 0.5,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[2] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[3] = (point_info){.required_x = 0,  .required_y = 0.2, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[4] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[5] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    
-
-
-
-
-////////////////////
-        
-    millisStart();
-    
-    
-        
-    Action.baud(115200);
-    Action.format(8,SerialBase::None,1); 
-    ActionEncoder_init();
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            char c = Action.getc();
-            if (readEncoder(c))
-            {
-                //startup_offset_x_encoder = now_x/1000;
-                //startup_offset_y_encoder = now_y/1000;
-                //startup_offset_w_encoder = now_w/float(180)*pi;
-                
-                start_calculatePos(  (now_x),(now_y), now_w  );   //global
-                break;
-            
-            }
-            
-        }
-    }    //start first to take offset from encoder... in case already moved
-    
- 
-   target_x    = points[0].required_x;  //  +  startup_offset_x_encoder;
-   target_y    = points[0].required_y;  //  +  startup_offset_y_encoder;
-   target_w    = points[0].required_w;   // -  startup_offset_w_encoder;
-    
-    
-    for( int a = 1; a < 2; a++ ){
-      action1.Enable();
-      action2.Enable();
-      action3.Enable();
-      wait(0.1);
-      action1.SetOperationalMode();
-      action2.SetOperationalMode();
-      action3.SetOperationalMode();
-      wait(0.1);
-      action1.Configvelocity(100000, 100000);
-      action2.Configvelocity(100000, 100000);
-      action3.Configvelocity(100000, 100000);  
-      wait(0.1);
-   }
-          
-    motor_updater.attach(&motor_update, RATE);  
-    //odom_updater.attach(&odom_update, RATE);
-    
-        
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            //pc.putc('a');
-            char c = Action.getc();
-            if(readEncoder(c)) odom_update();
-        }
-        
-    }
-
- 
-        
-/*
-        while (Action.readable()==1 ) 
-        {
-            char c = Action.getc();   
-            readEncoder(c);
-           
-        }
-*/
-    
-    
-/*
-    while(1)
-    {
-         
-         inverse(0.2,0,0);
-         wait(1);
-         inverse(-0.2,0,0);
-         wait(1);
-         
-         inverse(0,0,0.25);
-         wait(1);
-         inverse(0,0,-0.25);
-         wait(1);
-         
-    }
-    
-*/
-         
-
-    
-
-       
-}
--- a/main_stable.txt	Thu Oct 25 12:14:32 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,523 +0,0 @@
-#include "mbed.h"
-#include "actiondrv.h"
-
-#include "millis.h"
-
-/*
- * ActionEncoder.cpp
- *
- *  Created on: 7 Mar 2018
- *      Author: tung
- */
-
-#include "ActionEncoder.hpp"
-#include "Timer.h"
-
-
-
-///////////////////////////
-//Serial Action(D8,D2 ); // tx, rx
-Serial Action(PB_6,  PB_7 );
-Serial pc(USBTX, USBRX);
-
-
-
-union {
-    uint8_t data[24];
-    float val[6];
-} posture;
-int count=0;
-int i=0;
-int done=0;
-float xangle=0;
-float yangle=0;
-float zangle=0;
-float d_angle=0;
-float pos_x=0;
-float pos_y=0;
-float angleSpeed=0;
-float temp_zangle=0;
-int   LastRead=0;
-bool newDataArrived=false;
-
-char buffer[8];
-/////////////////////////
-
-//Serial pc(USBTX, USBRX);
-char counter = 0;
-actionDrv action1(1);
-actionDrv action2(2);
-actionDrv action3(3);
-
-
-int motor1 = 0;
-int motor2 = 0;
-int motor3 = 0;
-int motor4 = 0;
-
-float pi = 3.14159265;
-double pi_div_3 = 1.04719755;
-float d = 0.525;//0.43;
-float wheelR = 0.0508; //4 inch wheel
-float gear = 10;
-
-Ticker motor_updater;
-
-Ticker odom_updater;
-////////////////////////////////////
-float now_x=0;
-float now_y=0;
-float now_w=0;
-
-float target_x=0;
-float target_y=0;
-float target_w=0;
-
-float tolerance_x=0.02;
-float tolerance_y=0.02;
-float tolerance_w=0.01;
-
-float speed_max_x=1;
-float speed_max_y=1;
-float speed_max_w=0.1;
-
-long odom_last_read= millis();
-
-/////////////////////////////////////
-const float RATE = 0.18;
-
-///////////////////////////////////////
-int point_counter=0;
-
-struct point_info
-{
-   float required_x;
-   float required_y;
-   float required_w;
-   float required_tolerance_x;
-   float required_tolerance_y;
-   float required_tolerance_w;
-   float required_speed_max_x;
-   float required_speed_max_y;
-   float required_speed_max_w;
-};
-
-struct point_info points[100];
-
-
-
-
-///////////////////////////
-float encoder_2_global_angle = 30;         //encoder coordinate system + 30 degree    =>  global coordinate system
-float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
-float encoder_2_global_y     =   0.235;     //encoder to center distance  in y   (tung)
-////////////////////TUNG////////////////
-
-float    Xshift=  encoder_2_global_x;
-float    Yshift=  encoder_2_global_y;
-float    offsetX = -Yshift;
-float    offsetY = Xshift;
-
-float Ashift  =   -30*pi/float(180);
-float offsetA =   -30;
-
-float transformed_real_now_x=0;
-float transformed_real_now_y=0;
-float transformed_real_now_w=0;
-
-void calculatePos(float _X,float _Y,float _A)
-{
-    float radAng=_A/float(180)*pi;
-    /*
-    posX=(float(local_posY)/1000 + self.paraX * sin(w_radian) + self.paraY * cos(w_radian) )*(1) +self.offsetX
-    posY=(float(local_posX)/1000 + self.paraX * cos(w_radian) - self.paraY * sin(w_radian) )*(-1) +self.offsetY
-    */
-    float rotatedPosX=_X*cos(Ashift)+_Y*sin(Ashift);
-    float rotatedPosY=-_X*sin(Ashift)+_Y*cos(Ashift);
-    transformed_real_now_x=(rotatedPosY/float(1000)+Xshift*sin(radAng)+Yshift*cos(radAng))+offsetX;
-    transformed_real_now_y=(rotatedPosX/float(1000)+Xshift*cos(radAng)-Yshift*sin(radAng))*(-1)+offsetY;
-    //transformed_real_now_w=_A;   //
-    transformed_real_now_w=radAng;
-}
-
-
-
-
-
-///////////////////////
-float startup_offset_x_encoder = 0;
-float startup_offset_y_encoder = 0;
-float startup_offset_w_encoder = 0;
-
-
-float x_PID_P = 0.5;
-float y_PID_P = 0.5;
-float w_PID_P = 0.1;
-
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-
-//////////////////////////////
-
-void ActionEncoder_init()
-{
-    count=0;
-    i=0;
-    done=0;
-    xangle=0;
-    yangle=0;
-    zangle=0;
-    d_angle=0;
-    pos_x=0;
-    pos_y=0;
-    angleSpeed=0;
-    temp_zangle=0;
-    LastRead=0;
-    newDataArrived=false;
-
-}
-
-bool readEncoder(char c)
-{
-    //sprintf(buffer,"%02X",c);
-    //sprintf(buffer,"%X",c);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    
-    //sprintf(buffer,"%d",count);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    switch(count) {
-        case 0:
-            if (c==0x0d) count++;
-            else count=0;
-            break;
-        case 1:
-            if(c==0x0a) {
-                i=0;
-                count++;
-            } else if(c==0x0d) {}
-            else count=0;
-            break;
-        case 2:
-            posture.data[i]=c;
-            i++;
-            if(i>=24) {
-                i=0;
-                count++;
-            }
-            break;
-        case 3:
-            if(c==0x0a)count++;
-            else count=0;
-            break;
-        case 4:
-            if(c==0x0d) {
-                d_angle=posture.val[0]-temp_zangle;
-                if (d_angle<-180) {
-                    d_angle=d_angle+360;
-                } else if (d_angle>180) {
-                    d_angle=d_angle-360;
-                }
-                
-                now_w+=d_angle;
-                temp_zangle=posture.val[0];
-                //xangle=posture.val[1];
-                //yangle=posture.val[2];
-                now_x=posture.val[3];
-                now_y=posture.val[4];
-                //angleSpeed=posture.val[5];
-                newDataArrived=true;
-                
-            }
-            count=0;
-            done=1;
-            LastRead=millis();
-            return true;
-            //break;
-        default:
-            count=0;
-            break;
-    }
-    
-    return false;
-}
-
-bool updated()
-{
-    if (done) {
-        done=false;
-        return true;
-    } else {
-        return false;
-    }
-
-}
-
-float getXangle()
-{
-    return xangle;
-}
-
-float getYangle()
-{
-    return yangle;
-}
-
-float getZangle()
-{
-    return zangle;
-}
-
-float getXpos()
-{
-    return pos_x;
-}
-
-float getYpos()
-{
-    return pos_y;
-}
-
-float getAngleSpeed()
-{
-    return angleSpeed;
-}
-
-bool isAlive()
-{
-    if ((millis()-LastRead)<100) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-bool newDataAvailable()
-{
-    if (newDataArrived) {
-        newDataArrived=false;
-        return true;
-    } else return false;
-}
-
-char* reset()
-{
-    return "ACT0";
-}
-
-char* calibrate()
-{
-    return "ACTR";
-}
-
-
-void inverse(float x_vel, float y_vel, float w_vel)
-{
-    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
-    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    
-}
-
-
-
-void motor_update()
-{
-    action1.SetVelocity_mod(motor1  * -1 );
-    action2.SetVelocity_mod(motor2  * -1 );
-    action3.SetVelocity_mod(motor3  * -1 );
-    wait(0.005);
-}
-
-void odom_update()
-{
-
-   
-    calculatePos(now_x,now_y,now_w);
-    
-    /*
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-    
-    
-    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
-    {
-        point_counter+=1;
-
-       tolerance_x = points[point_counter].required_tolerance_x;
-       tolerance_y = points[point_counter].required_tolerance_x;
-       tolerance_w = points[point_counter].required_tolerance_x;
-       
-       target_x    = points[point_counter].required_x ;
-       target_y    = points[point_counter].required_y;
-       target_w    = points[point_counter].required_w  /float(180)*pi;
-       
-       inverse( 0    ,     0         ,     0   );
-       return;
-     
-    }
-    
-
-  
-    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
-    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
-    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
-    
-    
-    
-    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
-    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
-    
-    /*
-    pc.printf("X: ");
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  Y: ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  W: ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    
-    pc.printf(" | Global: ");
-    sprintf(buffer, "%f", global_vel_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", global_vel_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", local_vel_w);
-    pc.printf(buffer);*/
-    
-    
-  
-    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
-    
-    /*
-    pc.printf(" | Motor: ");
-    sprintf(buffer, "%d", motor1);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor2);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor3);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-}
-
-int main() {
-    //while(1){
-////////////////////////////
-    points[0] = (point_info){.required_x = 0.2,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[1] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    
-
-
-
-
-////////////////////
-        
-    millisStart();
-    
-    
-        
-    Action.baud(115200);
-    Action.format(8,SerialBase::None,1); 
-    ActionEncoder_init();
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            char c = Action.getc();
-            if (readEncoder(c))
-            {
-                startup_offset_x_encoder = now_x/1000;
-                startup_offset_y_encoder = now_y/1000;
-                startup_offset_w_encoder = now_w/float(180)*pi;
-                break;
-            
-            }
-            
-        }
-    }    //start first to take offset from encoder... in case already moved
-    
- 
-   target_x    = points[0].required_x;
-   target_y    = points[0].required_y;
-   target_w    = points[0].required_w;
-    
-    
-    for( int a = 1; a < 2; a++ ){
-      action1.Enable();
-      action2.Enable();
-      action3.Enable();
-      wait(0.1);
-      action1.SetOperationalMode();
-      action2.SetOperationalMode();
-      action3.SetOperationalMode();
-      wait(0.1);
-      action1.Configvelocity(100000, 100000);
-      action2.Configvelocity(100000, 100000);
-      action3.Configvelocity(100000, 100000);  
-      wait(0.1);
-   }
-          
-    motor_updater.attach(&motor_update, RATE);  
-    //odom_updater.attach(&odom_update, RATE);
-    
-        
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            char c = Action.getc();
-            if(readEncoder(c)) odom_update();
-        }
-        
-    }
-
- 
-        
-/*
-        while (Action.readable()==1 ) 
-        {
-            char c = Action.getc();   
-            readEncoder(c);
-           
-        }
-*/
-    
-    
-/*
-    while(1)
-    {
-         
-         inverse(0.2,0,0);
-         wait(1);
-         inverse(-0.2,0,0);
-         wait(1);
-         
-         inverse(0,0,0.25);
-         wait(1);
-         inverse(0,0,-0.25);
-         wait(1);
-         
-    }
-    
-*/
-         
-
-    
-
-       
-}
--- a/main_stable2_still_on9.txt	Thu Oct 25 12:14:32 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,583 +0,0 @@
-#include "mbed.h"
-#include "actiondrv.h"
-
-#include "millis.h"
-
-/*
- * ActionEncoder.cpp
- *
- *  Created on: 7 Mar 2018
- *      Author: tung
- */
-
-#include "ActionEncoder.hpp"
-#include "Timer.h"
-
-
-
-///////////////////////////
-//Serial Action(D8,D2 ); // tx, rx
-Serial Action(PB_6,  PB_7 );
-Serial pc(USBTX, USBRX);
-
-
-
-union {
-    uint8_t data[24];
-    float val[6];
-} posture;
-int count=0;
-int i=0;
-int done=0;
-float xangle=0;
-float yangle=0;
-float zangle=0;
-float d_angle=0;
-float pos_x=0;
-float pos_y=0;
-float angleSpeed=0;
-float temp_zangle=0;
-int   LastRead=0;
-bool newDataArrived=false;
-
-char buffer[8];
-/////////////////////////
-
-//Serial pc(USBTX, USBRX);
-char counter = 0;
-actionDrv action1(1);
-actionDrv action2(2);
-actionDrv action3(3);
-
-
-int motor1 = 0;
-int motor2 = 0;
-int motor3 = 0;
-int motor4 = 0;
-
-float pi = 3.14159265;
-double pi_div_3 = 1.04719755;
-float d = 0.525;//0.43;
-float wheelR = 0.0508; //4 inch wheel
-float gear = 10;
-
-Ticker motor_updater;
-
-Ticker odom_updater;
-////////////////////////////////////
-float now_x=0;
-float now_y=0;
-float now_w=0;
-
-float target_x=0;
-float target_y=0;
-float target_w=0;
-
-float tolerance_x=0.02;
-float tolerance_y=0.02;
-float tolerance_w=0.01;
-
-float speed_max_x=1;
-float speed_max_y=1;
-float speed_max_w=1;
-
-long odom_last_read= millis();
-
-/////////////////////////////////////
-const float RATE = 0.18;
-
-///////////////////////////////////////
-int point_counter=0;
-
-struct point_info
-{
-   float required_x;
-   float required_y;
-   float required_w;
-   float required_tolerance_x;
-   float required_tolerance_y;
-   float required_tolerance_w;
-   float required_speed_max_x;
-   float required_speed_max_y;
-   float required_speed_max_w;
-};
-
-struct point_info points[100];
-
-
-
-
-///////////////////////////
-float encoder_2_global_angle = 30;         //encoder coordinate system + 30 degree    =>  global coordinate system
-//float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
-//float encoder_2_global_y     =   -0.235;     //encoder to center distance  in y   (tung)
-
-
-float encoder_2_global_x     = 0.125;//0.125;// -0.13 ;    //encoder to center distance  in x   (tung)
-float encoder_2_global_y     = 0.37; //0.35;     //encoder to center distance  in y   (tung)
-////////////////////TUNG////////////////
-
-float    Xshift=  encoder_2_global_x;
-float    Yshift=  encoder_2_global_y;
-float    offsetX = -Yshift;
-float    offsetY = Xshift;
-
-float Ashift  =   -encoder_2_global_angle*pi/float(180);    //degree 2 rad
-float offsetA =   -encoder_2_global_angle;
-
-float transformed_real_now_x=0;
-float transformed_real_now_y=0;
-float transformed_real_now_w=0;
-
-
-float startup_offset_x_encoder =0;
-float startup_offset_y_encoder =0;
-float startup_offset_w_encoder=0;
-
-
-
-float encoder_to_center = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );
-
-
-void calculatePos(float _X,float _Y,float _A)
-{
-    float radAng=_A*pi/float(180);    //degree 2 rad
-    /*
-    posX=(float(local_posY)/1000 + self.paraX * sin(w_radian) + self.paraY * cos(w_radian) )*(1) +self.offsetX
-    posY=(float(local_posX)/1000 + self.pa+raX * cos(w_radian) - self.paraY * sin(w_radian) )*(-1) +self.offsetY
-    */
-    
-    /*
-    float rotatedPosX=_X*cos(Ashift)+_Y*sin(Ashift);
-    float rotatedPosY=-_X*sin(Ashift)+_Y*cos(Ashift);
-    transformed_real_now_x=(rotatedPosY/float(1000)+Xshift*sin(radAng)+Yshift*cos(radAng))+offsetX     -    startup_offset_x_encoder;
-    transformed_real_now_y=(rotatedPosX/float(1000)+Xshift*cos(radAng)-Yshift*sin(radAng))*(-1)+offsetY-    startup_offset_y_encoder;
-    */
-    
-    float rotatedPosX=  _X*cos(-Ashift)-_Y*sin(-Ashift);  
-    float rotatedPosY=  _X*cos(-Ashift)+_Y*sin(-Ashift);
-    
-    transformed_real_now_x=   rotatedPosY/float(1000)+    encoder_to_center  *sin(-radAng -Ashift)  +    0*cos(-radAng -Ashift)   -    startup_offset_x_encoder     ;
-    transformed_real_now_y=  (rotatedPosX/float(1000)+    encoder_to_center  *cos(-radAng -Ashift)  -    0*sin(-radAng -Ashift) )*-1   -    startup_offset_y_encoder    ;
-     
-     
-    transformed_real_now_w=radAng                                                                      -  startup_offset_w_encoder;
-}
-
-
-
-
-
-///////////////////////
-
-
-
-float x_PID_P = 0.5;
-float y_PID_P = 0.5;
-float w_PID_P = 1;
-
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-
-//////////////////////////////
-void start_calculatePos(float _X,float _Y,float _A)
-{
-    float radAng=_A*pi/float(180);    //degree 2 rad
-
-
-/*
-    float rotatedPosX=_X*cos(Ashift)+_Y*sin(Ashift);
-    float rotatedPosY=-_X*sin(Ashift)+_Y*cos(Ashift);
-    startup_offset_x_encoder  =  (rotatedPosY/float(1000)+Xshift*sin(radAng)+Yshift*cos(radAng))+offsetX;
-    startup_offset_y_encoder  =  (rotatedPosX/float(1000)+Xshift*cos(radAng)-Yshift*sin(radAng))*(-1)+offsetY;
-*/
-
-    float rotatedPosX=  _X*cos(-Ashift)-_Y*sin(-Ashift);  
-    float rotatedPosY=  _X*cos(-Ashift)+_Y*sin(-Ashift);
-    
-    startup_offset_x_encoder=   ((rotatedPosY/float(1000))+    encoder_to_center  *sin(-radAng -Ashift)  +    0*cos(-radAng -Ashift))   ; 
-    startup_offset_y_encoder = (((rotatedPosX/float(1000))+    encoder_to_center  *cos(-radAng -Ashift)  -    0*sin(-radAng -Ashift)) )*-1  ;
-   
-    startup_offset_w_encoder=radAng;
-}
-
-
-
-
-
-
-
-
-
-void ActionEncoder_init()
-{
-    count=0;
-    i=0;
-    done=0;
-    xangle=0;
-    yangle=0;
-    zangle=0;
-    d_angle=0;
-    pos_x=0;
-    pos_y=0;
-    angleSpeed=0;
-    temp_zangle=0;
-    LastRead=0;
-    newDataArrived=false;
-
-}
-
-bool readEncoder(char c)
-{
-    //sprintf(buffer,"%02X",c);
-    //sprintf(buffer,"%X",c);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    
-    //sprintf(buffer,"%d",count);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    switch(count) {
-        case 0:
-            if (c==0x0d) count++;
-            else count=0;
-            break;
-        case 1:
-            if(c==0x0a) {
-                i=0;
-                count++;
-            } else if(c==0x0d) {}
-            else count=0;
-            break;
-        case 2:
-            posture.data[i]=c;
-            i++;
-            if(i>=24) {
-                i=0;
-                count++;
-            }
-            break;
-        case 3:
-            if(c==0x0a)count++;
-            else count=0;
-            break;
-        case 4:
-            if(c==0x0d) {
-                d_angle=posture.val[0]-temp_zangle;
-                if (d_angle<-180) {
-                    d_angle=d_angle+360;
-                } else if (d_angle>180) {
-                    d_angle=d_angle-360;
-                }
-                
-                now_w+=d_angle;
-                temp_zangle=posture.val[0];
-                //xangle=posture.val[1];
-                //yangle=posture.val[2];
-                now_x=posture.val[3];
-                now_y=posture.val[4];
-                //angleSpeed=posture.val[5];
-                newDataArrived=true;
-                
-            }
-            count=0;
-            done=1;
-            LastRead=millis();
-            return true;
-            //break;
-        default:
-            count=0;
-            break;
-    }
-    
-    return false;
-}
-
-bool updated()
-{
-    if (done) {
-        done=false;
-        return true;
-    } else {
-        return false;
-    }
-
-}
-
-float getXangle()
-{
-    return xangle;
-}
-
-float getYangle()
-{
-    return yangle;
-}
-
-float getZangle()
-{
-    return zangle;
-}
-
-float getXpos()
-{
-    return pos_x;
-}
-
-float getYpos()
-{
-    return pos_y;
-}
-
-float getAngleSpeed()
-{
-    return angleSpeed;
-}
-
-bool isAlive()
-{
-    if ((millis()-LastRead)<100) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-bool newDataAvailable()
-{
-    if (newDataArrived) {
-        newDataArrived=false;
-        return true;
-    } else return false;
-}
-
-char* reset()
-{
-    return "ACT0";
-}
-
-char* calibrate()
-{
-    return "ACTR";
-}
-
-
-void inverse(float x_vel, float y_vel, float w_vel)
-{
-    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
-    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    
-}
-
-
-
-void motor_update()
-{
-    action1.SetVelocity_mod(motor1  * -1 );
-    action2.SetVelocity_mod(motor2  * -1 );
-    action3.SetVelocity_mod(motor3  * -1 );
-    wait(0.005);
-}
-
-void odom_update()
-{
-
-   
-    calculatePos(now_x,now_y,now_w);
-    
-    
-    /*sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    pc.printf("\r\n");
-    */
-    
-    
-    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
-    {
-        point_counter+=1;
-
-       tolerance_x = points[point_counter].required_tolerance_x;
-       tolerance_y = points[point_counter].required_tolerance_x;
-       tolerance_w = points[point_counter].required_tolerance_x;
-       
-       target_x    = points[point_counter].required_x                    ; //+    startup_offset_x_encoder;
-       target_y    = points[point_counter].required_y                    ; //+    startup_offset_y_encoder;
-       target_w    = points[point_counter].required_w  *pi/float(180);       ;//-    startup_offset_w_encoder;
-       
-       inverse( 0    ,     0         ,     0   );
-       return;
-     
-    }
-    
-
-  
-    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
-    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
-    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
-    
-    
-    
-    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
-    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
-    
-    /*
-    pc.printf("X: ");
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  Y: ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  W: ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    
-    pc.printf(" | Global: ");
-    sprintf(buffer, "%f", global_vel_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", global_vel_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", local_vel_w);
-    pc.printf(buffer);*/
-    
-    
-  
-    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
-    
-    /*
-    pc.printf(" | Motor: ");
-    sprintf(buffer, "%d", motor1);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor2);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor3);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-}
-
-int main() {
-    //while(1){
-////////////////////////////
-    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[1] = (point_info){.required_x = 0.5,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[2] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[3] = (point_info){.required_x = 0,  .required_y = 0.2, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[4] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[5] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[7] = (point_info){.required_x = 0,  .required_y = 0, .required_w = -90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[8] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    
-
-
-
-
-////////////////////
-        
-    millisStart();
-    
-    
-        
-    Action.baud(115200);
-    Action.format(8,SerialBase::None,1); 
-    ActionEncoder_init();
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            char c = Action.getc();
-            if (readEncoder(c))
-            {
-                //startup_offset_x_encoder = now_x/1000;
-                //startup_offset_y_encoder = now_y/1000;
-                //startup_offset_w_encoder = now_w/float(180)*pi;
-                
-                start_calculatePos(  (now_x),(now_y), now_w  );   //global
-                break;
-            
-            }
-            
-        }
-    }    //start first to take offset from encoder... in case already moved
-    
- 
-   target_x    = points[0].required_x;  //  +  startup_offset_x_encoder;
-   target_y    = points[0].required_y;  //  +  startup_offset_y_encoder;
-   target_w    = points[0].required_w *pi/float(180);   // -  startup_offset_w_encoder;
-    
-    
-    for( int a = 1; a < 2; a++ ){
-      action1.Enable();
-      action2.Enable();
-      action3.Enable();
-      wait(0.1);
-      action1.SetOperationalMode();
-      action2.SetOperationalMode();
-      action3.SetOperationalMode();
-      wait(0.1);
-      action1.Configvelocity(100000, 100000);
-      action2.Configvelocity(100000, 100000);
-      action3.Configvelocity(100000, 100000);  
-      wait(0.1);
-   }
-          
-    motor_updater.attach(&motor_update, RATE);  
-    //odom_updater.attach(&odom_update, RATE);
-    
-        
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            //pc.putc('a');
-            char c = Action.getc();
-            if(readEncoder(c)) odom_update();
-        }
-        
-    }
-
- 
-        
-/*
-        while (Action.readable()==1 ) 
-        {
-            char c = Action.getc();   
-            readEncoder(c);
-           
-        }
-*/
-    
-    
-/*
-    while(1)
-    {
-         
-         inverse(0.2,0,0);
-         wait(1);
-         inverse(-0.2,0,0);
-         wait(1);
-         
-         inverse(0,0,0.25);
-         wait(1);
-         inverse(0,0,-0.25);
-         wait(1);
-         
-    }
-    
-*/
-         
-
-    
-
-       
-}
--- a/main_stable_ex_1_2018_10_25.txt	Thu Oct 25 12:14:32 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,591 +0,0 @@
-#include "mbed.h"
-#include "actiondrv.h"
-
-#include "millis.h"
-
-/*
- * ActionEncoder.cpp
- *
- *  Created on: 7 Mar 2018
- *      Author: tung
- */
-
-#include "ActionEncoder.hpp"
-#include "Timer.h"
-
-
-
-///////////////////////////
-//Serial Action(D8,D2 ); // tx, rx
-Serial Action(PB_6,  PB_7 );
-Serial pc(USBTX, USBRX);
-
-
-
-union {
-    uint8_t data[24];
-    float val[6];
-} posture;
-int count=0;
-int i=0;
-int done=0;
-float xangle=0;
-float yangle=0;
-float zangle=0;
-float d_angle=0;
-float pos_x=0;
-float pos_y=0;
-float angleSpeed=0;
-float temp_zangle=0;
-int   LastRead=0;
-bool newDataArrived=false;
-
-char buffer[8];
-/////////////////////////
-
-//Serial pc(USBTX, USBRX);
-char counter = 0;
-actionDrv action1(1);
-actionDrv action2(2);
-actionDrv action3(3);
-
-
-int motor1 = 0;
-int motor2 = 0;
-int motor3 = 0;
-int motor4 = 0;
-
-float pi = 3.14159265;
-double pi_div_3 = 1.04719755;
-float d = 0.525;//0.43;
-float wheelR = 0.0508; //4 inch wheel
-float gear = 10;
-
-Ticker motor_updater;
-
-Ticker odom_updater;
-////////////////////////////////////
-float now_x=0;
-float now_y=0;
-float now_w=0;
-
-float target_x=0;
-float target_y=0;
-float target_w=0;
-
-float tolerance_x=0.02;
-float tolerance_y=0.02;
-float tolerance_w=0.01;
-
-float speed_max_x=1;
-float speed_max_y=1;
-float speed_max_w=1;
-
-long odom_last_read= millis();
-
-/////////////////////////////////////
-const float RATE = 0.18;
-
-///////////////////////////////////////
-int point_counter=0;
-
-struct point_info
-{
-   float required_x;
-   float required_y;
-   float required_w;
-   float required_tolerance_x;
-   float required_tolerance_y;
-   float required_tolerance_w;
-   float required_speed_max_x;
-   float required_speed_max_y;
-   float required_speed_max_w;
-};
-
-struct point_info points[100];
-
-
-
-
-///////////////////////////
-float encoder_2_global_angle = 30;         //encoder coordinate system + 30 degree    =>  global coordinate system
-//float encoder_2_global_x     =   0.34;    //encoder to center distance  in x   (tung)
-//float encoder_2_global_y     =   -0.235;     //encoder to center distance  in y   (tung)
-
-
-float encoder_2_global_x     = 0.125;//0.125;// -0.13 ;    //encoder to center distance  in x   (tung)
-float encoder_2_global_y     = 0.37; //0.35;     //encoder to center distance  in y   (tung)
-////////////////////TUNG////////////////
-
-
-float transformed_real_now_x=0;
-float transformed_real_now_y=0;
-float transformed_real_now_w=0;
-
-
-float startup_offset_x_encoder =0;
-float startup_offset_y_encoder =0;
-float startup_offset_w_encoder=0;
-
-
-
-float encoder_to_center = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );
-
-//#########################//
-float encoder2local_angle = 30 *pi/float(180);
-float encoder_position_angle =( ( 180 + 18.666914)  ) / float(180) * pi ;   //90 +  angle to encoder location
-float r = sqrt( ( encoder_2_global_x  * encoder_2_global_x )  + ( encoder_2_global_y  *  encoder_2_global_y ) );   //encoder to center radius
-
-
-void calculatePos(float _X,float _Y,float _A)
-{
-    float zangle  =  _A-   360 * int(_A / 360);
-    float zrangle =  zangle *pi/float(180);    //degree 2 rad
-    
-    float tx = ( ( _X / float(1000) ) * cos( -encoder2local_angle) )  -  (  ( _Y / float(1000) )   *  sin( -encoder2local_angle) );
-    float ty = ( ( _X / float(1000) ) * sin( -encoder2local_angle) )  +  (  ( _Y / float(1000) )   *  cos( -encoder2local_angle) );
-    
-    float s  = copysign( sqrt(  2*( r*r )  -  2*(r*r)*cos(zrangle)  )    , zrangle );
-    
-    float x_bias = s * cos( zrangle / 2 );
-    float y_bias = s * sin( zrangle / 2 );
-    
-    float x_tbias = ( x_bias ) * ( cos( encoder_position_angle) )  - ( y_bias ) * ( sin( encoder_position_angle ) )    ;
-    float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
-    
-    
-   // transformed_real_now_x = tx - x_tbias   - startup_offset_x_encoder;
-   // transformed_real_now_y = ty - y_tbias   - startup_offset_y_encoder;
-    
-    transformed_real_now_x = tx + y_tbias   - startup_offset_x_encoder;
-    transformed_real_now_y = ty - x_tbias   - startup_offset_y_encoder;
-    
-    
-    transformed_real_now_w=   _A *pi/float(180)                                                                        -  startup_offset_w_encoder;
-    
-    
-}
-
-
-
-
-
-///////////////////////
-
-
-
-float x_PID_P = 0.5;
-float y_PID_P = 0.5;
-float w_PID_P = 1;
-
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-
-//////////////////////////////
-void start_calculatePos(float _X,float _Y,float _A)
-{
-    float zangle  =  _A-   360 * int(_A / 360);
-    float zrangle =  zangle *pi/float(180);    //degree 2 rad
-    
-    float tx = ( ( _X / float(1000) ) * cos( -encoder2local_angle) )  -  (  ( _Y / float(1000) )   *  sin( -encoder2local_angle) );
-    float ty = ( ( _X / float(1000) ) * sin( -encoder2local_angle) )  +  (  ( _Y / float(1000) )   *  cos( -encoder2local_angle) );
-    
-    float s  = copysign( sqrt(  2*( r*r )  -  2*(r*r)*cos(zrangle)  )    , zrangle );
-    
-    float x_bias = s * cos( zrangle / 2 );
-    float y_bias = s * sin( zrangle / 2 );
-    
-    float x_tbias = ( x_bias ) * ( cos( encoder_position_angle) )  - ( y_bias ) * ( sin( encoder_position_angle ) )    ;
-    float y_tbias = ( x_bias ) * ( sin( encoder_position_angle) )  + ( y_bias ) * ( cos( encoder_position_angle ) )    ;
-    
-    
-  //  startup_offset_x_encoder = tx - x_tbias ;
-  //  startup_offset_y_encoder = ty - y_tbias ;
-    
-    startup_offset_x_encoder = tx + y_tbias ;
-    startup_offset_y_encoder = ty - x_tbias ;
-    
-    
-    startup_offset_w_encoder =  _A *pi/float(180);    //degree 2 rad
-    
-    
-}
-
-
-
-
-
-
-
-void ActionEncoder_init()
-{
-    count=0;
-    i=0;
-    done=0;
-    xangle=0;
-    yangle=0;
-    zangle=0;
-    d_angle=0;
-    pos_x=0;
-    pos_y=0;
-    angleSpeed=0;
-    temp_zangle=0;
-    LastRead=0;
-    newDataArrived=false;
-
-}
-
-bool readEncoder(char c)
-{
-    //sprintf(buffer,"%02X",c);
-    //sprintf(buffer,"%X",c);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    
-    //sprintf(buffer,"%d",count);
-    //pc.printf(buffer);
-    //pc.printf("\r\n");
-    switch(count) {
-        case 0:
-            if (c==0x0d) count++;
-            else count=0;
-            break;
-        case 1:
-            if(c==0x0a) {
-                i=0;
-                count++;
-            } else if(c==0x0d) {}
-            else count=0;
-            break;
-        case 2:
-            posture.data[i]=c;
-            i++;
-            if(i>=24) {
-                i=0;
-                count++;
-            }
-            break;
-        case 3:
-            if(c==0x0a)count++;
-            else count=0;
-            break;
-        case 4:
-            if(c==0x0d) {
-                d_angle=posture.val[0]-temp_zangle;
-                if (d_angle<-180) {
-                    d_angle=d_angle+360;
-                } else if (d_angle>180) {
-                    d_angle=d_angle-360;
-                }
-                
-                now_w+=d_angle;
-                temp_zangle=posture.val[0];
-                //xangle=posture.val[1];
-                //yangle=posture.val[2];
-                now_x=posture.val[3];
-                now_y=posture.val[4];
-                //angleSpeed=posture.val[5];
-                newDataArrived=true;
-                
-            }
-            count=0;
-            done=1;
-            LastRead=millis();
-            return true;
-            //break;
-        default:
-            count=0;
-            break;
-    }
-    
-    return false;
-}
-
-bool updated()
-{
-    if (done) {
-        done=false;
-        return true;
-    } else {
-        return false;
-    }
-
-}
-
-float getXangle()
-{
-    return xangle;
-}
-
-float getYangle()
-{
-    return yangle;
-}
-
-float getZangle()
-{
-    return zangle;
-}
-
-float getXpos()
-{
-    return pos_x;
-}
-
-float getYpos()
-{
-    return pos_y;
-}
-
-float getAngleSpeed()
-{
-    return angleSpeed;
-}
-
-bool isAlive()
-{
-    if ((millis()-LastRead)<100) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-bool newDataAvailable()
-{
-    if (newDataArrived) {
-        newDataArrived=false;
-        return true;
-    } else return false;
-}
-
-char* reset()
-{
-    return "ACT0";
-}
-
-char* calibrate()
-{
-    return "ACTR";
-}
-
-
-void inverse(float x_vel, float y_vel, float w_vel)
-{
-    motor1  =  int(   (    (-1) * sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    motor2  =  int(   (    (-1) *  y_vel + d * w_vel                                                )  * 60 / (wheelR * 2 * pi)  * gear   ); 
-    motor3  =  int(   (           sin(pi_div_3) * x_vel   +  cos(pi_div_3) * y_vel +  d * w_vel     )  * 60 / (wheelR * 2 * pi)  * gear   );
-    
-}
-
-
-
-void motor_update()
-{
-    action1.SetVelocity_mod(motor1  * -1 );
-    action2.SetVelocity_mod(motor2  * -1 );
-    action3.SetVelocity_mod(motor3  * -1 );
-    wait(0.005);
-}
-
-void odom_update()
-{
-
-   
-    calculatePos(now_x,now_y,now_w);
-    
-    
-    /*sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    pc.printf("\r\n");
-    */
-    
-    
-    if ((    (fabs(target_x - transformed_real_now_x)) < tolerance_x ) && (   (fabs(target_y - transformed_real_now_y)) < tolerance_y )  && (   (fabs(target_w - transformed_real_now_w)) < tolerance_w )      )
-    {
-        point_counter+=1;
-
-       tolerance_x = points[point_counter].required_tolerance_x;
-       tolerance_y = points[point_counter].required_tolerance_x;
-       tolerance_w = points[point_counter].required_tolerance_x;
-       
-       target_x    = points[point_counter].required_x                    ; //+    startup_offset_x_encoder;
-       target_y    = points[point_counter].required_y                    ; //+    startup_offset_y_encoder;
-       target_w    = points[point_counter].required_w  *pi/float(180);       ;//-    startup_offset_w_encoder;
-       
-       inverse( 0    ,     0         ,     0   );
-       return;
-     
-    }
-    
-
-  
-    float local_vel_x = (fabs(target_x - transformed_real_now_x) > tolerance_x ) ?   constrain(  (x_PID_P * (target_x - transformed_real_now_x)    ), -speed_max_x,    speed_max_x)  : 0 ;
-    float local_vel_y = (fabs(target_y - transformed_real_now_y) > tolerance_y ) ?   constrain(  (y_PID_P * (target_y - transformed_real_now_y)    ), -speed_max_y,    speed_max_y)  : 0 ;
-    float local_vel_w = (fabs(target_w - transformed_real_now_w) > tolerance_w ) ?   constrain(  (w_PID_P * (target_w - transformed_real_now_w)    ), -speed_max_w,    speed_max_w)  : 0 ;
-    
-    
-    
-    float global_vel_x = local_vel_x * cos( -transformed_real_now_w  )  -  local_vel_y * sin( -transformed_real_now_w ); 
-    float global_vel_y = local_vel_x * sin( -transformed_real_now_w  )  +  local_vel_y * cos( -transformed_real_now_w );  //local to global transformation   (angle only)
-    
-    /*
-    pc.printf("X: ");
-    sprintf(buffer, "%f", transformed_real_now_x);
-    pc.printf(buffer);
-    pc.printf("  Y: ");
-    sprintf(buffer, "%f", transformed_real_now_y);
-    pc.printf(buffer);
-    pc.printf("  W: ");
-    sprintf(buffer, "%f", transformed_real_now_w);
-    pc.printf(buffer);
-    
-    pc.printf(" | Global: ");
-    sprintf(buffer, "%f", global_vel_x);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", global_vel_y);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%f", local_vel_w);
-    pc.printf(buffer);*/
-    
-    
-  
-    inverse( global_vel_x   ,  global_vel_y       ,     local_vel_w   );
-    
-    /*
-    pc.printf(" | Motor: ");
-    sprintf(buffer, "%d", motor1);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor2);
-    pc.printf(buffer);
-    pc.printf("  ");
-    sprintf(buffer, "%d", motor3);
-    pc.printf(buffer);
-    pc.printf("\r\n");*/
-    
-}
-
-int main() {
-    //while(1){
-////////////////////////////
-    points[0] = (point_info){.required_x = 0,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[1] = (point_info){.required_x = 0.5,.required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[2] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[3] = (point_info){.required_x = 0,  .required_y = 0.2, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[4] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[5] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[6] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[7] = (point_info){.required_x = 0,  .required_y = 0, .required_w = -90, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    points[8] = (point_info){.required_x = 0,  .required_y = 0, .required_w = 0, .required_tolerance_x = 0.05, .required_tolerance_y = 0.05, .required_tolerance_w = 0.01, .required_speed_max_x = 0.3, .required_speed_max_y = 0.3, .required_speed_max_w = 0.01};
-    
-
-
-
-
-////////////////////
-        
-    millisStart();
-    
-    
-        
-    Action.baud(115200);
-    Action.format(8,SerialBase::None,1); 
-    ActionEncoder_init();
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            char c = Action.getc();
-            if (readEncoder(c))
-            {
-                //startup_offset_x_encoder = now_x/1000;
-                //startup_offset_y_encoder = now_y/1000;
-                //startup_offset_w_encoder = now_w/float(180)*pi;
-                
-                start_calculatePos(  (now_x),(now_y), now_w  );   //global
-                break;
-            
-            }
-            
-        }
-    }    //start first to take offset from encoder... in case already moved
-    
- 
-   target_x    = points[0].required_x;  //  +  startup_offset_x_encoder;
-   target_y    = points[0].required_y;  //  +  startup_offset_y_encoder;
-   target_w    = points[0].required_w *pi/float(180);   // -  startup_offset_w_encoder;
-    
-    
-    for( int a = 1; a < 2; a++ ){
-      action1.Enable();
-      action2.Enable();
-      action3.Enable();
-      wait(0.1);
-      action1.SetOperationalMode();
-      action2.SetOperationalMode();
-      action3.SetOperationalMode();
-      wait(0.1);
-      action1.Configvelocity(100000, 100000);
-      action2.Configvelocity(100000, 100000);
-      action3.Configvelocity(100000, 100000);  
-      wait(0.1);
-   }
-          
-    motor_updater.attach(&motor_update, RATE);  
-    //odom_updater.attach(&odom_update, RATE);
-    
-        
-    while(1) 
-    {
-        if (Action.readable())
-        {
-            //pc.putc('a');
-            char c = Action.getc();
-            if(readEncoder(c)) odom_update();
-        }
-        
-    }
-
- 
-        
-/*
-        while (Action.readable()==1 ) 
-        {
-            char c = Action.getc();   
-            readEncoder(c);
-           
-        }
-*/
-    
-    
-/*
-    while(1)
-    {
-         
-         inverse(0.2,0,0);
-         wait(1);
-         inverse(-0.2,0,0);
-         wait(1);
-         
-         inverse(0,0,0.25);
-         wait(1);
-         inverse(0,0,-0.25);
-         wait(1);
-         
-    }
-    
-*/
-         
-
-    
-
-       
-}