velocity.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "runCtrl.h"
00010 #include <unistd.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <sys/time.h>
00014 #include <signal.h>
00015
00016 enum {
00017 Right = 0, Left = 1,
00018 DefaultAcc = 100,
00019 };
00020
00021 typedef void (callback_t)(int);
00022
00023 static RunCtrl Run;
00024 static int EncRefVel = 0;
00025 static int EncRefAcc = DefaultAcc;
00026 static int TotalTicks = 0;
00027 static int PreTicks = 0;
00028
00029
00030 static void setIntervalTimer(callback_t *func, int interval_msec) {
00031 struct itimerval itimer;
00032 struct sigaction act;
00033
00034
00035 itimer.it_value.tv_sec = 0;
00036 itimer.it_value.tv_usec = interval_msec * 1000;
00037 itimer.it_interval.tv_sec = 0;
00038 itimer.it_interval.tv_usec = interval_msec * 1000;
00039 setitimer(ITIMER_REAL, &itimer, NULL);
00040
00041
00042 act.sa_handler = func;
00043 sigemptyset(&act.sa_mask);
00044 act.sa_flags = 0;
00045
00046 sigaction(SIGALRM, &act, 0);
00047 }
00048
00049
00050 static void stopIntervalTimer(void) {
00051 struct itimerval itimer;
00052 itimer.it_value.tv_sec = 0;
00053 itimer.it_value.tv_usec = 0;
00054 setitimer(ITIMER_REAL, &itimer, NULL);
00055 }
00056
00057
00058 static int getTicks(void) {
00059 struct timeval time;
00060 gettimeofday(&time, NULL);
00061 return (time.tv_sec * 1000) + (time.tv_usec / 1000);
00062 }
00063
00064
00065 static void setRefVelocity(int mm_sec_vel, int mm_sec_acc = DefaultAcc) {
00066
00067
00068 EncRefVel = static_cast<int>(mm_sec_vel * WHL_CNT_PER_MM_RIGHT / 1000);
00069 EncRefAcc = static_cast<int>(mm_sec_acc * WHL_CNT_PER_MM_RIGHT / 1000);
00070
00071 printf("EncRefVel: %d, EncRefAcc: %d\n", EncRefVel, EncRefAcc);
00072 }
00073
00074
00075 static void initVelocityCtrl(void) {
00076 PreTicks = getTicks();
00077 }
00078
00079
00080 static int calcPwmValue(int EncRefVel, int* enc_vel, int* diff_total) {
00081 double Gain_P = 0.000004;
00082 double Gain_I = 0.00001;
00083
00084 int diff = EncRefVel - *enc_vel;
00085 *diff_total += diff;
00086
00087 double output = (Gain_P * diff) + (Gain_I * *diff_total);
00088 double duty = output * 255.0;
00089
00090 int pwm = (fabs(duty) > 1.0) ?
00091 static_cast<int>(255 * duty/fabs(duty)) : static_cast<int>(255 * duty);
00092
00093 return static_cast<int>(pwm);
00094 }
00095
00096
00097 static void velocityCtrl(int sig) {
00098 static bool initialized = false;
00099 if (!initialized) {
00100 initialized = true;
00101 initVelocityCtrl();
00102 return;
00103 }
00104 static int pwm[2];
00105 static int diff_total[2] = { 0, 0 };
00106
00107
00108 int now = getTicks();
00109 int interval_msec = now - PreTicks;
00110 TotalTicks += interval_msec;
00111 PreTicks = now;
00112 printf("ticks: %d (%d) [msec]\n", TotalTicks, interval_msec);
00113
00114
00115 int enc_vel[2];
00116 for (int i = 0; i < 2; ++i) {
00117
00118 enc_vel[i] *= -1;
00119 }
00120
00121
00122 int ref_enc_vel = TotalTicks * EncRefAcc;
00123 ref_enc_vel = (ref_enc_vel > EncRefVel) ? EncRefVel : ref_enc_vel;
00124 for (int i = 0; i < 2; ++i) {
00125 pwm[i] = calcPwmValue(ref_enc_vel, &enc_vel[i], &diff_total[i]);
00126 }
00127
00128
00129 for (int i = 0; i < 2; ++i) {
00130
00131
00132
00133 }
00134
00135 printf("ref_enc_vel: %d\n", ref_enc_vel);
00136 printf("enc_vel: %d, %d\n", enc_vel[Right], enc_vel[Left]);
00137 printf("pwm: %d, %d\n", pwm[Right], pwm[Left]);
00138 printf("\n");
00139 }
00140
00141
00142 int main(int argc, char *argv[]) {
00143 try {
00144 enum { IntervalMsec = 130 };
00145
00146
00147 if (Run.connect(argc, argv) < 0) {
00148 printf("RunCtrl::connect: %s\n", Run.what());
00149 exit(1);
00150 }
00151
00152
00153 setRefVelocity(100);
00154 setIntervalTimer(velocityCtrl, IntervalMsec);
00155
00156
00157 while (getchar() == EOF) {
00158 sleep(1);
00159 }
00160
00161 stopIntervalTimer();
00162 Run.stop();
00163 } catch (std::exception& e) {
00164 printf("exception: %s\n", e.what());
00165 }
00166 return 0;
00167 }
00168