utility.h
utility.c
usart.h
usart.c
#ifndef __UTILITY #define __UTILITY float d_cos(float x); int itoa(char *a, int x); int itoaw(char *a, int x, unsigned int width); int itoh(char *a, unsigned int x); int ftoa(char *a, float x, int precision); float atof(char *a); int atoi(char *a); float angle(float value); // 0<t<360 float angle2(float value); // -180<t<180 #define PI 3.14159265359f #define DEG_TO_RAD (PI / 180) //#define SQR2 1.41421356 //#define RECSQR2 0.70710678 //逆数 #define square(x) ((x) * (x)) int ipower(int value, int n); //n乗 int isqrt(int a); //平方根 int sgn(int value); //符号 int iabs(int value); //絶対値 float fAbs(float value); int pmod(int val1, unsigned int val2); int limit_zero(int value); int limit_max(int value, int max); int limit_min(int value, int min); int limit_scope(int value, int min, int max); float flimit_scope(float value, float min, float max); #endif /*__UTILITY */
utility.c
#include "utility.h"
#define TABLESIZE 128 //2の乗数であること
#define SUBBIT 8
#define SUBINDEX (1 << SUBBIT)
#define I_PI (TABLESIZE * SUBINDEX * 2)
#define I_HPI (TABLESIZE * SUBINDEX)
//int(sin(index / (pi / 2) * 128) * 65535 + 0.5)
const unsigned short sin_table[] = {
0, 804, 1608, 2412, 3216, 4019, 4821, 5623,
6424, 7223, 8022, 8820, 9616, 10411, 11204, 11996,
12785, 13573, 14359, 15142, 15924, 16703, 17479, 18253,
19024, 19792, 20557, 21319, 22078, 22834, 23586, 24334,
25079, 25820, 26557, 27291, 28020, 28745, 29465, 30181,
30893, 31600, 32302, 32999, 33692, 34379, 35061, 35738,
36409, 37075, 37736, 38390, 39039, 39682, 40319, 40950,
41575, 42194, 42806, 43411, 44011, 44603, 45189, 45768,
46340, 46905, 47464, 48014, 48558, 49095, 49624, 50145,
50659, 51166, 51664, 52155, 52638, 53113, 53580, 54039,
54490, 54933, 55367, 55794, 56211, 56620, 57021, 57413,
57797, 58171, 58537, 58895, 59243, 59582, 59913, 60234,
60546, 60850, 61144, 61429, 61704, 61970, 62227, 62475,
62713, 62942, 63161, 63371, 63571, 63762, 63943, 64114,
64276, 64428, 64570, 64703, 64826, 64939, 65042, 65136,
65219, 65293, 65357, 65412, 65456, 65491, 65515, 65530,
65535, 0
};
float d_cos(float x){
long ix, subix, sign, tval;
ix = (int)(x * (I_PI / 180.f)); //単位変換
ix += I_HPI;
sign = ix & I_PI; //第3,第4象限である
ix &= (I_PI - 1); //第1,第2象限に限定
if(ix > I_HPI) ix = I_PI - ix; //第1象限に限定
subix = ix & (SUBINDEX - 1); //線形補完に用いるサブインデックス
ix >>= SUBBIT; //テーブル番号に変換
//線形補完
tval = ((long)sin_table[ix] * (SUBINDEX - subix)
+ (long)sin_table[ix+1] * subix);
return (sign ? -tval : tval) / (SUBINDEX * 65535.f);
}
//角度を0~360degの範囲に収める
float angle(float value){
while(1){
if(value < 0){
value += 360;
}else if(value >= 360){
value -= 360;
}else{
break;
}
}
return(value);
}
//角度を-180~180degの範囲に収める
float angle2(float value){
while(1){
if(value < -180){
value += 360;
}else if(value >= 180){
value -= 360;
}else{
break;
}
}
return(value);
}
//整数のn乗
int ipower(int value, int n){
int ret = 1;
for(;n>0;n--){
ret *= value;
}
return(ret);
}
//整数の平方根近似
/*int isqrt(int a)
{
int i;
//a /= 2;
a >>= 1;
for (i = 1; a > 0; i++) a -= i;
return i - 1;
}*/
int isqrt(int f)
{
int s = f, t;
if (f == 0) return 0;
do
{
t = s;
s = (t + f / t) >> 1;
} while (s < t);
return t;
}
//整数の符号を返す
int sgn(int value){
if(value > 0){
return 1;
}else if(value < 0){
return -1;
}
return 0;
}
//整数の絶対値
int iabs(int value){
return (value < 0 ? -value : value);
}
//実数の絶対値
float fAbs(float value){
return (value < 0 ? -value : value);
}
//常に正の余りを返す
int pmod(int val1, unsigned int val2){
val1 = val1 % (int)val2;
if(val1 < 0) val1 += val2;
return val1;
}
//0以下の値を0に切り上げ
int limit_zero(int value){
return ((value < 0) ? 0 : value);
}
//max以上の値をmaxに切り下げ
int limit_max(int value, int max){
return ((value > max) ? max : value);
}
//min以下の値をminに切り上げ
int limit_min(int value, int min){
return ((value < min) ? min : value);
}
//範囲内に切り上げまたは切り下げ
int limit_scope(int value, int min, int max){
if(value < min){
value = min;
}else if(value > max){
value = max;
}
return(value);
}
//実数を範囲内に切り上げまたは切り下げ
float flimit_scope(float value, float min, float max){
if(value < min){
value = min;
}else if(value > max){
value = max;
}
return(value);
}
int itoa(char *a, int x){
return itoaw(a, x, 0);
}
int itoaw(char *a, int x, unsigned int width){
int place = 1000000000;
int firstnum = 0;
int k, n = 0;
if(x < 0){
a[0] = '-';
n++;
x = -x;
}
while(place){
k = x / place;
if(k || width >= 10) firstnum = 1;
if(firstnum || place == 1){
a[n] = '0' + k;
n++;
x -= k * place;
}
place /= 10;
width++;
}
a[n] = 0;
return(n);
}
int itoh(char *a, unsigned int x){
unsigned int place = 0x80000000;
int firstnum = 0;
int k, n = 0;
while(place){
k = x / place;
if(k) firstnum = 1;
if(firstnum || place == 1){
a[n] = (k < 10) ? ('0' + k) : (('A' - 10) + k);
n++;
x -= k * place;
}
place >>= 4;
}
a[n] = 0;
return(n);
}
int ftoa(char *a, float x, int precision){
int n = 0;
if(x < 0){
a[0] = '-';
n++;
x = -x;
}
n += itoa(a + n, (int)x);
x -= (int)x;
if(precision > 0){
a[n] = '.';
n++;
n += itoaw(a + n, (int)(x * ipower(10, precision)), precision);
}
return(n);
}
float atof(char *a){
float ret = 0;
int pointed = 0;
char psgn = 0;
if(*a == '-'){
psgn = 1;
a++;
}
while(*a != 0){
if('0' <= *a && *a <= '9'){
if(pointed){
ret += (float)(*a - '0') / (float)pointed;
pointed *= 10;
}else{
ret *= 10;
ret += (float)(*a - '0');
}
}else if(*a == '.'){
pointed = 10;
}else{
break;
}
a++;
}
return psgn ? -ret : ret;
}
int atoi(char *a){
int ret = 0;
char psgn = 0;
if(*a == '-'){
psgn = 1;
a++;
}
while(*a != 0){
if('0' <= *a && *a <= '9'){
ret *= 10;
ret += (int)(*a - '0');
}else{
break;
}
a++;
}
return psgn ? -ret : ret;
}
usart.h
#include <stdarg.h> void usart_init(); void usart_putc(const char c); void usart_putc_nowait(const char c); char usart_getc(); void usart_printstr(const char* str); void usart_inputstr(char* str); void usart_scanstr(char* str); void usart_printint(int val); void usart_printfloat(float value, int decimal); int usart_received(); void usart_printf(const char *fmt, ...); void roboterm_clear(); void roboterm_settarget(int number); void roboterm_setlabel(int number, const char* str); void roboterm_setvalue(int number, const char* str); void roboterm_setvalueint(int number, int value); void roboterm_setvaluef(int number, float value, int decimal); void roboterm_setcategory(const char *a); float roboterm_fgetparam(const char *name); int roboterm_igetparam(const char *name); void roboterm_sgetparam(const char *name, char *str); void roboterm_selecttab(int index);
usart.c
#include "stm32f10x.h"
#include "usart.h"
#include "utility.h"
#define ROBOTERM
//USART Control Functions ///////////////////////////////////////////////////////
#define CHAR_NULL 0x00
#define CHAR_CR 0x0d
#define CHAR_LF 0x0a
//改行コードはWindows仕様に
#define PUT_NEWLINE usart_putc(CHAR_CR); usart_putc(CHAR_LF)
void usart_init(){
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 250000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);
}
void usart_putc(const char c){
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, c);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void usart_putc_nowait(const char c){
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, c);
}
char usart_getc(){
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USART1);USART_ReceiveData(USART1);
}
int usart_received(){
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){
return 0;
}
return 1;
}
//文字列を送信する
void usart_printstr(const char* str){
while(*str != CHAR_NULL) {
if(*str == '\n'){
PUT_NEWLINE;
}else{
usart_putc(*str);
}
str++;
}
}
//文字列を受け取り、リターンで終了
void usart_inputstr(char* str){
char c;
while(1){
c = usart_getc();
if(c == CHAR_CR){
*str = CHAR_NULL;
break;
}
*str = c;
str++;
}
}
//入力を逐次再送信し、リターンで終了
void usart_scanstr(char* str){
char c;
while(1){
c = usart_getc();
if(c == CHAR_CR){
usart_putc(CHAR_CR);
usart_putc(CHAR_LF);
*str = CHAR_NULL;
break;
}
usart_putc(c);
*str = c;
str++;
}
}
#ifdef __UTILITY
void usart_printint(int value){
char a[10];
itoa(a, value);
usart_printstr(a);
}
void usart_printfloat(float value, int decimal){
char a[10];
ftoa(a, value, decimal);
usart_printstr(a);
}
//簡易版printf: %d, %sのみ対応
//フィールド幅などの指定は不可
void usart_printf(const char *fmt, ...){
va_list ap;
va_start(ap, fmt);
while(*fmt != CHAR_NULL) {
if(*fmt == '%'){
fmt++;
if(*fmt == 'd') usart_printint(va_arg(ap, int));
else if(*fmt == 's') usart_printstr(va_arg(ap, const char *));
else if(*fmt == '%') usart_putc('%');
}else if(*fmt == '\n'){
PUT_NEWLINE;
}else{
usart_putc(*fmt);
}
fmt++;
}
va_end(ap);
}
#endif
#ifdef ROBOTERM
void roboterm_clear(){
usart_printstr("@CL:");
}
void roboterm_settarget(int number){
usart_printstr("@V");
usart_printint(number);
usart_printstr(":");
}
void roboterm_setlabel(int number, const char* str){
usart_printstr("@L");
usart_printint(number);
usart_printstr(":");
usart_printstr(str);
}
void roboterm_setvalue(int number, const char* str){
usart_printstr("@V");
usart_printint(number);
usart_printstr(":");
usart_printstr(str);
}
void roboterm_setvalueint(int number, int value){
usart_printstr("@V");
usart_printint(number);
usart_printstr(":");
usart_printint(value);
}
void roboterm_setvaluef(int number, float value, int decimal){
usart_printstr("@V");
usart_printint(number);
usart_printstr(":");
usart_printfloat(value, decimal);
}
void roboterm_setcategory(const char *a){
usart_printstr("@PC");
usart_printstr(a);
usart_printstr(":");
}
float roboterm_fgetparam(const char *name){
char a[10];
usart_printstr("@PG");
usart_printstr(name);
usart_printstr(":");
usart_inputstr(a);
return(atof(a));
}
int roboterm_igetparam(const char *name){
char a[10];
usart_printstr("@PG");
usart_printstr(name);
usart_printstr(":");
usart_inputstr(a);
return(atoi(a));
}
void roboterm_sgetparam(const char *name, char *str){
usart_printstr("@PG");
usart_printstr(name);
usart_printstr(":");
usart_inputstr(str);
}
void roboterm_selecttab(int index){
usart_printstr("@T");
usart_printint(index);
usart_printstr(":");
}
#endif
//減速に必要な距離の2乗
float nl2 = square((square(im.speed) - square(target_speed)) / (2 * deccel));
float dl = im.target_u - u;
float dl2 = square(dl);
float dlf2 = square(dl - stabilityLength); //目標までの距離の2乗
if(dl <= stabilityLength){ //距離調整
//1ステップで速度調整するために必要な加速度
im.accel = (target_speed - im.speed) * dti;
//加速度の制限
im.accel = flimit_scope(im.accel, -deccel, deccel);
}else if(dlf2 <= nl2 && im.speed > 120){ //速度調整(発進時は猶予を)
if(dl2 < nl2){ //間に合わなさそうなときは加速度を増す
deccel += DA * dt;
if(deccel > maxaccel) deccel = maxaccel;
}
if(target_speed < im.speed){
im.accel = -deccel;
}else{
//加速度を上げる時は加速度上昇量を守る
im.accel += flimit_scope(deccel - im.accel, -DA * dt, DA * dt);
}
accelmode = 0; //一旦減速したら最加速はしない
}else if(!accelmode){
//残りの距離が余ったら、加速度を少し落とす
deccel -= DA * dt;
if(target_speed < im.speed) im.accel = -deccel; else im.accel = deccel;
}else if(im.speed < maxspd
&& !(dl < HALFBLOCK && im.speed >= target_speed)){ //目標まで半区画以下で目標速度以上の加速を禁止
if(im.speed > ACCREST_SPEED){ // ある速度以上では加速度を制限する
if(im.accel > adaccel * 0.75f) im.accel -= DA * dt;
}else{
if(im.accel < adaccel) im.accel += DA * dt;
}
}else{
im.accel = 0;
}
im.speed += im.accel * dt;
if(im.speed < SPEED_MINIMUM) im.speed = SPEED_MINIMUM;
im.u = u + im.speed * dt;
if(im.u >= im.target_u){
im.u = im.target_u;
im.accel = 0;
Backyard.tcount = 0;
Backyard.command_index++; Backyard_OperationCommand(0);//次のコマンドに
}

最新コメント