DRのPS3での操作用(アームの開閉をコントローラで制御可能)

Dependencies:   mbed CalPID motorout ros_lib_melodic MotorController_AbsEC

main.cpp

Committer:
ayu13
Date:
2021-07-10
Revision:
5:4fba3e91741f
Parent:
4:3abefa13c2e3
Child:
6:e6b303ea6439

File content as of revision 5:4fba3e91741f:

////c = center arm
#include "mbed.h"
#include "AMT21.h"
#include "CalPID.h"
#include "KondoServo.h"
#include "MotorController.h"
#include <stdlib.h>
#include <ros.h>
#include <std_msgs/String.h>
#include <geometry_msgs/Point.h>

/////////////////               宣言部分                  //////////////////////
#ifndef M_PI
#define M_PI 3.14159265359f
#endif
#define DELTA_T 0.01        //制御周期
#define DUTY_MAX 0.07       //duty比の最大値
#define OMEGA_MAX 0.6       //速度制御を利用した角度制御での角速度の最大値
#define NUM_DATA 270

int state = 0;

////角度制御(アブソリュートエンコーダ)/////
DigitalOut myled1(LED1);
Timer timer;
CalPID speed_pid(0.08,0,0.0008,DELTA_T,DUTY_MAX);   //速度制御のPD計算
CalPID angle_duty_pid(0,0,0,DELTA_T,DUTY_MAX);   //角度制御(duty式)のPD計算
CalPID angle_omega_pid(5.5,0,0.0032,DELTA_T,OMEGA_MAX);//角度制御(速度式)のPD計算
Amt21 amt(p9,p10,p8);    //Amt21 (PinName tx,PinName rx,PinName mode):serial_(tx,rx),rs485_mode(mode)
MotorController motor(p26,p25,DELTA_T,amt,speed_pid,angle_duty_pid,angle_omega_pid);    //MotorController(PinName motor_p_, PinName motor_n_,double dt, Amt21 &ec, CalPID &sc_, CalPID &ac_duty, CalPID &ac_omega)
double radToDeg(double x);
double degToRad(double x);
double target_speed=0;
double target_rad=0;
double target_deg = 0;
double right_deg = -90;
double left_deg = 90;

////先端アーム(サーボ)/////
DigitalIn ts_c1(p6, PullUp);
DigitalIn ts_c2(p7, PullUp);
KondoServo servo_c(p13, p14);
double servoDeg(double servo_value);
void touchGrab();
int id_c1 = 0;
float deg_c_grab = 10000;
float deg_c_open = 7500;
int hand = 0;   //タッチセンサがONになった状態:1,OFF:0

////データ記録まわり/////
int angle_count=0;
int omega_count=0;
double now_deg=0;
double now_count=0;

/////////////////               ROS               /////////////////
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
float arm_num=0,arm_deg=0,arm_rad=0;
void cArmCallback(const geometry_msgs::Point &arm_state)
{
    arm_num = arm_state.x;        //右回転=1、左回転=2
    arm_deg = arm_state.y;        //目標角度
}
ros::NodeHandle  nh;
ros::Subscriber<geometry_msgs::Point> sub("/arm",&cArmCallback);

int main()
{
    myled1 = 0;     //目標角度以上離れている:点灯
    myled2 = 0;     //通信で欲しい値が送られているとき:点灯
    myled3 = 0;     //
    myled4 = 0;     //サーボを掴む→点灯.離す→消灯

    /////////       ROS       /////////
    nh.getHardware()->setBaud(921600);
    nh.initNode();
    nh.subscribe(sub);

    timer.reset();
    timer.start();

    motor.setEquation(0.0523,0.0148,0.0459,-0.0341);    //Excel"omega_controll"の図より

//    target_rad = -(M_PI/6); //目標角度をπ/6(rad)に(単位に注意)           //////////////////////////
//    target_deg = radToDeg(target_rad);

    while (1) {
        ////    ROS     ////
        nh.spinOnce();

        if(timer.read()>DELTA_T) {
            if(arm_num==1&&arm_deg==30) {       //動作確認用
                myled2 = 1;
            }
            arm_rad = degToRad(arm_deg);
//        target_rad = -arm_rad;
//        target_deg = -arm_deg;
            arm_deg = -30;
            arm_rad = degToRad(arm_deg);

            if(state == 0) {
                target_deg = -60;
                target_rad = degToRad(target_deg);
                state++;
            } else if (state == 1) {
                myled3 = 1;
                if(fabs(now_deg-target_deg) > 0.5) {      //現在角度と目標角度が0.5°以上離れている間回す
                    myled1 = 1;   //LED1 点灯
                    motor.AcOmega(target_rad);   //速度式角度制御
                } else { //目標角度に達したら停止
                    myled1=0;   //LED1 消灯
                    motor.stop();
                }
                touchGrab();                //タッチセンサ
            } else if (state == 2) {
                myled3 = 0;
                target_rad = arm_rad;
                target_deg = arm_deg;
                state++;
            } else if (state == 3) {
                if(fabs(now_deg-target_deg) > 0.5) {      //現在角度と目標角度が0.5°以上離れている間回す
                    myled1 = 1;   //LED1 点灯
                    motor.AcOmega(target_rad);   //速度式角度制御
                } else { //目標角度に達したら停止
                    myled1=0;   //LED1 消灯
                    motor.stop();
                    //wait(100);    //table停止用時間
                    servo_c.set_degree(0,servoDeg(deg_c_open));   //servo_c離す
                    myled4 = 0;
                }
            }

            ////タッチセンサ////
//        touchGrab();

            ////アブソリュートエンコーダ////

//            if(fabs(now_deg-target_deg) > 0.5) {      //現在角度と目標角度が0.5°以上離れている間回す
//                myled1 = 1;   //LED1 点灯
////                if(hand == 1) {     //タッチセンサが反応していたとき(ハンドルを掴んでいたとき)
//                motor.AcOmega(target_rad);   //速度式角度制御
////                } else if(hand == 0) {
////                    myled4=0;   //LED4 消灯
////                }
//            } else if(fabs(now_deg-target_deg) < 0.5 && state == 3) { //目標角度に達したら停止
//                myled1=0;   //LED1 消灯
//                motor.stop();
//                hand = 0;
//                //wait(100);    //table停止用時間
//                servo_c.set_degree(0,servoDeg(deg_c_open));   //servo_c離す
//            }
            amt.rewriteCount();
            amt.calOmega();
            amt.getOmega();
            now_deg = amt.getDeg();
            now_count=amt.getCount();
//            motor.AcOmega(target_rad);

            timer.reset();
        }
        wait_us(10);
    }
}

/////////////////               関数宣言部分                  //////////////////////
double servoDeg(double servo_value)
{
    return (servo_value - 3500)*270/(11500 - 3500);
}
double radToDeg(double x)
{
    return x*180/M_PI;
}
double degToRad(double x)
{
    return x*M_PI/180;
}
void touchGrab()
{
    if(ts_c1 == 0) {      //タッチセンサ反応したらハンドルを掴む
        wait_us(50);
        if(ts_c1 == 0) {
            servo_c.set_degree(0,servoDeg(deg_c_grab));   //servo_c掴む
            state++;
//            hand = 1;
            myled4=1;   //LED4 点灯
        }
    }
}