先看主程式
int main(int argc, char *argv[]){
//initializing Network communication remote.create(); /* Waiting fo Start command */ while (true){ remote.exec_remoteCMD(); usleep(2000); }//end |
}
再來看 net.h
| class Socket{ | |
| private: | |
| sockaddr_in m_address; | |
| unsigned short m_port; | |
| int m_socket; | |
| unsigned char m_lastdata[256]; | |
| int get_cmd(float& ,float& ,float& ,float&); | |
| int get_cmd(); | |
| public: | |
| Socket(); | |
| ~Socket(); | |
| void set_port(int port); | |
| void create(); | |
| void Close(); | |
| void exec_remoteCMD(); | |
| unsigned char data[256]; | |
| }; | |
| extern Socket remote; |
發覺他 宣告了一個 Socket 物件 . 名字叫做 remote
| void Socket::create() | |
| { | |
| //Opening socket | |
| m_socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); | |
| if ( m_socket <= 0 ) | |
| { | |
| printf( "Failed to create socket\n" ); | |
| exit(EXIT_FAILURE); | |
| } | |
| //Binding to desired port number | |
| if ( bind( m_socket, (const sockaddr*) &m_address, sizeof(sockaddr_in) ) < 0 ) | |
| { | |
| perror( "failed to bind socket"); | |
| exit(EXIT_FAILURE); | |
| } | |
| //setting Socket to non blocking mode | |
| int nonBlocking = 1; | |
| if ( fcntl( m_socket, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 ) | |
| { | |
| printf( "failed to set non-blocking socket\n" ); | |
| exit(EXIT_FAILURE); | |
| } | |
| printf( "Succeed to create socket\nWaiting for Instructions...\n" ); | |
| } |
| void Socket::exec_remoteCMD() | |
| { | |
| //PID variables | |
| float kp_,ki_,kd_; | |
| switch(get_cmd()){ | |
| //returns 1 for Start(Initialize) | |
| //returns 2 for Initialize | |
| //returns 10 for yawstab PID constants | |
| //returns 11 for yawrate PID constants | |
| //returns 12 for PRstab PID constants | |
| //returns 13 for PRrate PID constants | |
| case NOTHING: | |
| //nothing to do here | |
| break; | |
| case SHUTDOWN: | |
| //On Shutdown : | |
| //stop Timer | |
| Timer.stop(); | |
| if (Timer.started){ | |
| printf("toto"); | |
| } | |
| //close socket | |
| Close(); | |
| //stop servos | |
| if (ESC.Is_open_blaster()){ | |
| ESC.stopServo(); | |
| ESC.close_blaster(); | |
| } | |
| //shutdown | |
| system("sudo shutdown -h now"); | |
| //exit quad_pilot | |
| exit(1); | |
| //printf("PID stopped \n"); | |
| break; | |
| case UPDATE_REMOTE: | |
| //set rcinput values values | |
| parser.parse(data,Timer.thr,Timer.ypr_setpoint); | |
| break; | |
| case UPDATE_PID_YAW_STAB: | |
| //set pid constants YAW Stab | |
| parser.parse(data,kp_,ki_,kd_); | |
| yprSTAB[YAW].set_Kpid(kp_,ki_,kd_); | |
| break; | |
| case UPDATE_PID_YAW_RATE: | |
| //set pid constants YAW Rate | |
| parser.parse(data,kp_,ki_,kd_); | |
| yprRATE[YAW].set_Kpid(kp_,ki_,kd_); | |
| break; | |
| case UPDATE_PID_PR_STAB: | |
| //set pid constants | |
| parser.parse(data,kp_,ki_,kd_); | |
| yprSTAB[PITCH].set_Kpid(kp_,ki_,kd_); | |
| yprSTAB[ROLL].set_Kpid(kp_,ki_,kd_); | |
| //printf("PID: %7.2f %7.2f %7.2f \n",kp_,ki_,kd_); | |
| break; | |
| case UPDATE_PID_PR_RATE: | |
| //set pid constants | |
| parser.parse(data,kp_,ki_,kd_); | |
| yprRATE[PITCH].set_Kpid(kp_,ki_,kd_); | |
| yprRATE[ROLL].set_Kpid(kp_,ki_,kd_); | |
| //printf("PID: %7.5f %7.5f %7.5f \n",kp_,ki_,kd_); | |
| break; | |
| case INIT: | |
| //intialization of IMU | |
| if (!Timer.started && !imu.initialized){ | |
| imu.set_com(); | |
| imu.initialize(); | |
| } | |
| //initilization of PID constants | |
| yprRATE[YAW].set_Kpid(3.5,0.1,0.1); | |
| yprRATE[PITCH].set_Kpid(2.9,0.1,0.125); | |
| yprRATE[ROLL].set_Kpid (2.9,0.1,0.125); | |
| yprSTAB[PITCH].set_Kpid(3.3,0.035,0.04); | |
| yprSTAB[ROLL].set_Kpid(3.3,0.035,0.04); | |
| break; | |
| case STOP_PID: | |
| //On exit : | |
| //stop Timer | |
| Timer.stop(); | |
| //stop servos | |
| if (ESC.Is_open_blaster()){ | |
| ESC.stopServo(); | |
| ESC.close_blaster(); | |
| } | |
| //reset PID | |
| for (int i=0;i<DIM;i++) yprSTAB[i].reset(); | |
| for (int i=0;i<DIM;i++) yprRATE[i].reset(); | |
| printf("PID Stopped \n"); | |
| break; | |
| case START_PID: | |
| //Remote says "Start" | |
| if (Timer.started){ | |
| //PID already running | |
| break; | |
| } else if (!imu.initialized){ | |
| //IMU not initialized | |
| printf("DMP not Initalized\n Can't start...\n"); | |
| break; | |
| } | |
| //Initializing ESCs | |
| printf("Initialization of ESC...\n"); | |
| ESC.open_blaster(); | |
| ESC.init(); | |
| printf(" ... DONE.\n"); | |
| //Things are getting started ! | |
| //launch the Alarm signal | |
| Timer.start(); | |
| while (Timer.started){ | |
| sleep(1000); | |
| } | |
| }//end switch | |
| return; | |
| } |
| int Socket::get_cmd(){ | |
| int type=0; | |
| //returns 1 for Start | |
| //returns 2 for Initialize | |
| //returns 666 for Exit | |
| //retunrs 10 for yaw PID constants | |
| //retunrs 11 for yawrate PID constants | |
| //retunrs 12 for PR PID constants | |
| //retunrs 13 for PRrate PID constants | |
| //returns 0 for rcinputs (default) | |
| int size = sizeof(data); | |
| assert( size > 0 ); | |
| if ( m_socket == 0 ) | |
| printf("Socket is closed..."); | |
| int received_bytes = -1; | |
| sockaddr_in from; | |
| socklen_t fromLength = sizeof( from ); | |
| received_bytes = recvfrom( m_socket, data, size, 0, | |
| (sockaddr*)&from, | |
| &fromLength); | |
| if (received_bytes == -1){ | |
| //printf("received bytes = -1 \n"); | |
| return NOTHING; | |
| } | |
| std::string packet( reinterpret_cast< char const* > (data)); | |
| std::istringstream ss(packet); | |
| std::string sub; | |
| ss >> sub; | |
| do{ | |
| if (sub == "START"){ | |
| type = START_PID; | |
| break; | |
| }else if (sub == "STOP"){ | |
| type = STOP_PID; | |
| break; | |
| }else if (sub == "EXIT"){ | |
| type = SHUTDOWN; | |
| break; | |
| }else if (sub == "INIT"){ | |
| type = INIT; | |
| break; | |
| } else if(sub == "pid"){ | |
| ss >> sub; | |
| if (sub == "yaw_rate"){ | |
| type = UPDATE_PID_YAW_RATE; | |
| break; | |
| }else if (sub == "yaw_stab"){ | |
| type = UPDATE_PID_YAW_STAB; | |
| break; | |
| }else if (sub == "pr_stab"){ | |
| type = UPDATE_PID_PR_STAB; | |
| break; | |
| }else if (sub == "pr_rate"){ | |
| type = UPDATE_PID_PR_RATE; | |
| break; | |
| } | |
| } else { break; } | |
| }while(ss); | |
| // printf("%d\n",type); | |
| return(type); | |
| } |
重點就是.....
Timer.start(); while (Timer.started){ sleep(1000); } |
| void TimerClass::sig_handler_(int signum) | |
| { | |
| pthread_mutex_lock(&TimerMutex_); | |
| //1-Get and Execute Command from remote | |
| remote.exec_remoteCMD(); | |
| //2- get attitude of the drone | |
| imu.getAttitude(); | |
| // printf("ATTITUDE: %7.2f %7.2f %7.2f\n",imu.ypr[YAW], | |
| // imu.ypr[PITCH], | |
| // imu.ypr[ROLL]); | |
| //3- Timer dt | |
| Timer.calcdt_(); | |
| //4-1 Calculate PID on attitude | |
| // if (abs(Timer.ypr_setpoint[YAW])<5) { | |
| // Timer.ypr_setpoint[YAW] = imu.ypr[YAW]; | |
| // } | |
| #ifdef PID_STAB | |
| //Stabilization is only done on Pitch and Roll | |
| //Yaw is Rate PID only | |
| for (int i=1;i<DIM;i++){ | |
| Timer.PIDout[i] = | |
| yprSTAB[i].update_pid_std(Timer.ypr_setpoint[i], | |
| imu.ypr[i], | |
| Timer.dt); | |
| } | |
| Timer.PIDout[0] = Timer.ypr_setpoint[0]; | |
| // printf("PITCH: %7.2f %7.2f %7.2f\n",Timer.ypr_setpoint[PITCH], | |
| // imu.ypr[PITCH], | |
| // Timer.PIDout[PITCH]); | |
| // printf("ROLL: %7.2f %7.2f %7.2f\n",Timer.ypr_setpoint[ROLL], | |
| // imu.ypr[ROLL], | |
| // Timer.PIDout[ROLL]); | |
| for (int i=0;i<DIM;i++){ | |
| Timer.PIDout[i] = | |
| yprRATE[i].update_pid_std(Timer.PIDout[i], | |
| imu.gyro[i], | |
| Timer.dt); | |
| } | |
| // printf("YAW: %7.2f %7.2f %7.2f\n",Timer.ypr_setpoint[YAW], | |
| // imu.gyro[YAW], | |
| // Timer.PIDout[YAW]); | |
| // printf("PITCH: %7.2f %7.2f %7.2f\n",Timer.ypr_setpoint[PITCH], | |
| // imu.gyro[PITCH], | |
| // Timer.PIDout[PITCH]); | |
| // printf("ROLL: %7.2f %7.2f %7.2f\n",Timer.ypr_setpoint[ROLL], | |
| // imu.gyro[ROLL], | |
| // Timer.PIDout[ROLL]); | |
| #endif | |
| //4-2 Calculate PID on rotational rate | |
| #ifdef PID_RATE | |
| for (int i=0;i<DIM;i++){ | |
| Timer.PIDout[i] = | |
| yprRATE[i].update_pid_std(Timer.ypr_setpoint[i], | |
| imu.gyro[i], | |
| Timer.dt); | |
| } | |
| //printf("%7.2f %7.2f\n",imu.gyro[PITCH],Timer.PIDout[PITCH]); | |
| #endif | |
| //5- ESC update and compensate Timer | |
| // if timer has not been stopped | |
| if (Timer.started){ | |
| ESC.update(Timer.thr,Timer.PIDout); | |
| //printf("%7.2f %7.2f\n",Timer.thr,Timer.PIDout[ROLL]); | |
| Timer.compensate_(); | |
| } | |
| pthread_mutex_unlock(&TimerMutex_); | |
| } |
接下來看
| //2- get attitude of the drone | |
| imu.getAttitude(); |
| void DMP::getAttitude() | |
| { | |
| if (!dmpReady) return; | |
| // wait for FIFO count > 42 bits | |
| do { | |
| fifoCount = mpu.getFIFOCount(); | |
| }while (fifoCount<42); | |
| if (fifoCount == 1024) { | |
| // reset so we can continue cleanly | |
| mpu.resetFIFO(); | |
| printf("FIFO overflow!\n"); | |
| // otherwise, check for DMP data ready interrupt | |
| //(this should happen frequently) | |
| } else { | |
| //read packet from fifo | |
| mpu.getFIFOBytes(fifoBuffer, packetSize); | |
| mpu.dmpGetQuaternion(&q, fifoBuffer); | |
| mpu.dmpGetGravity(&gravity, &q); | |
| mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); | |
| ypr[0]-=m_ypr_off[0]; | |
| //scaling for degrees output | |
| for (int i=0;i<DIM;i++){ | |
| //no offset removal | |
| //should be accounted while triming | |
| //ypr[i]-=m_ypr_off[i]; | |
| ypr[i]*=180/M_PI; | |
| } | |
| //printf(" %7.2f %7.2f %7.2f\n",ypr[0],ypr[1],ypr[2]); | |
| //unwrap yaw when it reaches 180 | |
| ypr[0] = wrap_180(ypr[0]); | |
| //change sign of Pitch, MPU is attached upside down | |
| ypr[1]*=-1.0; | |
| mpu.dmpGetGyro(g, fifoBuffer); | |
| //0=gyroX, 1=gyroY, 2=gyroZ | |
| //swapped to match Yaw,Pitch,Roll | |
| //Scaled from deg/s to get tr/s | |
| for (int i=0;i<DIM;i++){ | |
| gyro[i] = (float)(g[DIM-i-1])/131.0/360.0; | |
| } | |
| // printf("gyro %7.2f %7.2f %7.2f \n", (float)g[0]/131.0, | |
| // (float)g[1]/131.0, | |
| // (float)g[2]/131.0); | |
| } | |
| } |
#define YAW 0
#define PITCH 1
#define ROLL 2
#define DIM 3
//3- Timer dt
| inline void TimerClass::calcdt_() | |
| { | |
| oldtime_ = time_; | |
| clock_gettime(CLOCK_MONOTONIC, &time_); | |
| Timer.dt = ((static_cast <int64_t>(time_.tv_sec) * 1000000000 + | |
| static_cast <int64_t>(time_.tv_nsec)) - | |
| (static_cast <int64_t>(oldtime_.tv_sec) * 1000000000 + | |
| static_cast <int64_t>(oldtime_.tv_nsec))) / 1000000000.0; | |
| } | |
//4-1 Calculate PID on attitude
|
extern PID yprRATE[3];
//5- ESC update and compensate Timer // if timer has not been stopped if (Timer.started){ ESC.update(Timer.thr,Timer.PIDout); //printf("%7.2f %7.2f\n",Timer.thr,Timer.PIDout[ROLL]); Timer.compensate_(); }
|

沒有留言:
張貼留言