diff --git a/Makefile b/Makefile index 19efbc3d6a6797b84b6d1b7bbca0e18875466d98..03acfec959fc69b72f0d2bcbd6385f1980b7cd59 100755 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ $(BUILD_PATH)/%.o: $(USART_PATH)/src/%.c $(CC) -c $(CFLAGS) -o $@ $< $(MAIN_OUT_ELF): mkdir_build $(BIOLOID_OBJS) $(BUID_PATH)/$(STARTUP_FILE:.s=.o) - $(LD) $(LDFLAGS) $(BIOLOID_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(EXT_LIB) --output $@ + $(LD) $(LDFLAGS) $(BIOLOID_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(EXT_LIB) -lm --output $@ $(MAIN_OUT_HEX): $(MAIN_OUT_ELF) $(OBJCP) $(OBJCPFLAGS_HEX) $< $@ diff --git a/include/action.h b/include/action.h index 165841c6358b878366ad9b1515088b5425b8200f..adc182caebb376bab8247e6f3639932eee758919 100644 --- a/include/action.h +++ b/include/action.h @@ -8,9 +8,6 @@ extern "C" { #include "stm32f4xx.h" #include "motion_pages.h" -extern int64_t action_current_angles[PAGE_MAX_NUM_SERVOS]; -extern uint8_t action_slope[PAGE_MAX_NUM_SERVOS]; - // public functions void action_init(uint16_t period_us); inline void action_set_period(uint16_t period_us); diff --git a/include/bioloid_kinematics.h b/include/bioloid_kinematics.h new file mode 100755 index 0000000000000000000000000000000000000000..21662e4eafb58a278a58182ca1c6ea9853e18636 --- /dev/null +++ b/include/bioloid_kinematics.h @@ -0,0 +1,25 @@ +#ifndef _BIOLOID_KINEMATICS_H +#define _BIOLOID_KINEMATICS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32f4xx.h" + +#define BIOLOID_LEG_SIDE_OFFSET 38.5 //mm +#define BIOLOID_PELVIS_LENGTH 29.0 //mm +#define BIOLOID_THIGH_LENGTH 76.388 //mm +#define BIOLOID_CALF_LENGTH 76.388 //mm +#define BIOLOID_KNEE_DEPTH 14.5 //mm +#define BIOLOID_ANKLE_LENGTH 33.68 //mm +#define BIOLOID_LEG_LENGTH (BIOLOID_THIGH_LENGTH + BIOLOID_CALF_LENGTH + BIOLOID_ANKLE_LENGTH) //mm + +// public functions +uint8_t bioloid_leg_ik(float *out, float x, float y, float z, float a, float b, float c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/bioloid_math.h b/include/bioloid_math.h new file mode 100755 index 0000000000000000000000000000000000000000..fb47cbd74b167d1833825a729c05724fedf092aa --- /dev/null +++ b/include/bioloid_math.h @@ -0,0 +1,62 @@ +#ifndef _BIOLOID_MATH_H +#define _BIOLOID_MATH_H + +#include "stm32f4xx.h" + +#define PI 3.14159 + +typedef struct{ + float x; + float y; + float z; +}TPoint3D; + +// point public functions +void point3d_init(TPoint3D *point); +void point3d_load(TPoint3D *point, float x, float y, float z); +void point3d_copy(TPoint3D *point_dst, TPoint3D *point_src); + +typedef struct { + float x; + float y; + float z; +}TVector3D; + +// vector public functions +void vector3d_init(TVector3D *vector); +void vector3d_load(TVector3D *vector, float x, float y, float z); +void vector3d_copy(TVector3D *vector_dst, TVector3D *vector_src); +float vector3d_length(TVector3D *vector); + +enum{ + m00=0, + m01, + m02, + m03, + m10, + m11, + m12, + m13, + m20, + m21, + m22, + m23, + m30, + m31, + m32, + m33, +}; + +typedef struct{ + float coef[16]; +}TMatrix3D; + +// matrix public functions +void matrix3d_init(TMatrix3D *matrix); +void matrix3d_copy(TMatrix3D *matrix_dst, TMatrix3D *matrix_src); +void matrix3d_identity(TMatrix3D *matrix); +uint8_t matrix3d_inverse(TMatrix3D *org, TMatrix3D *inv); +void matrix3d_set_transform(TMatrix3D *matrix, TPoint3D *point, TVector3D *vector); +void matrix3d_mult(TMatrix3D *dst,TMatrix3D *a,TMatrix3D *b); + +#endif diff --git a/include/bioloid_registers.h b/include/bioloid_registers.h index 54f7994babffa26bd1b10409f811af1846fbc203..3a18e31db477ea33f2527f5f7964e25df0ba6a27 100644 --- a/include/bioloid_registers.h +++ b/include/bioloid_registers.h @@ -50,6 +50,23 @@ extern "C" { #define MM_SERVO31_OFFSET ((unsigned short int)0x0030) #define GYRO_FB_ADC_CH_OFFSET ((unsigned short int)0x0031) #define GYRO_LR_ADC_CH_OFFSET ((unsigned short int)0x0032) +#define WALK_X_OFFSET ((unsigned short int)0x0033) +#define WALK_Y_OFFSET ((unsigned short int)0x0034) +#define WALK_Z_OFFSET ((unsigned short int)0x0035) +#define WALK_ROLL_OFFSET ((unsigned short int)0x0036) +#define WALK_PITCH_OFFSET ((unsigned short int)0x0037) +#define WALK_YAW_OFFSET ((unsigned short int)0x0038) +#define WALK_HIP_PITCH_OFF ((unsigned short int)0x0039) +#define WALK_PERIOD_TIME ((unsigned short int)0x003B) +#define WALK_DSP_RATIO ((unsigned short int)0x003D) +#define WALK_STEP_FW_BW_RATIO ((unsigned short int)0x003E) +#define WALK_FOOT_HEIGHT ((unsigned short int)0x003F) +#define WALK_SWING_RIGHT_LEFT ((unsigned short int)0x0040) +#define WALK_SWING_TOP_DOWN ((unsigned short int)0x0041) +#define WALK_PELVIS_OFFSET ((unsigned short int)0x0042) +#define WALK_ARM_SWING_GAIN ((unsigned short int)0x0043) +#define WALK_MAX_VEL ((unsigned short int)0x0044) +#define WALK_MAX_ROT_VEL ((unsigned short int)0x0045) #define LAST_EEPROM_OFFSET ((unsigned short int)0x00FF) @@ -105,6 +122,25 @@ typedef enum { BIOLOID_MM_SERVO31_OFFSET = MM_SERVO31_OFFSET, // angle offset in fixed point format 1-3|4 BIOLIOD_GYRO_FB_ADC_CH = GYRO_FB_ADC_CH_OFFSET, BIOLIOD_GYRO_LR_ADC_CH = GYRO_LR_ADC_CH_OFFSET, + BIOLOID_WALK_X_OFFSET = WALK_X_OFFSET, + BIOLOID_WALK_Y_OFFSET = WALK_Y_OFFSET, + BIOLOID_WALK_Z_OFFSET = WALK_Z_OFFSET, + BIOLOID_WALK_ROLL_OFFSET = WALK_ROLL_OFFSET, + BIOLOID_WALK_PITCH_OFFSET = WALK_PITCH_OFFSET, + BIOLOID_WALK_YAW_OFFSET = WALK_YAW_OFFSET, + BIOLOID_WALK_HIP_PITCH_OFF_L = WALK_HIP_PITCH_OFF, + BIOLOID_WALK_HIP_PITCH_OFF_H = WALK_HIP_PITCH_OFF+1, + BIOLOID_WALK_PERIOD_TIME_L = WALK_PERIOD_TIME, + BIOLOID_WALK_PERIOD_TIME_H = WALK_PERIOD_TIME+1, + BIOLOID_WALK_DSP_RATIO = WALK_DSP_RATIO, + BIOLOID_WALK_STEP_FW_BW_RATIO = WALK_STEP_FW_BW_RATIO, + BIOLOID_WALK_FOOT_HEIGHT = WALK_FOOT_HEIGHT, + BIOLOID_WALK_SWING_RIGHT_LEFT = WALK_SWING_RIGHT_LEFT, + BIOLOID_WALK_SWING_TOP_DOWN = WALK_SWING_TOP_DOWN, + BIOLOID_WALK_PELVIS_OFFSET = WALK_PELVIS_OFFSET, + BIOLOID_WALK_ARM_SWING_GAIN = WALK_ARM_SWING_GAIN, + BIOLOID_WALK_MAX_VEL = WALK_MAX_VEL, + BIOLOID_WALK_MAX_ROT_VEL = WALK_MAX_ROT_VEL, BIOLOID_USER1_LED_CNTRL = 0x0100, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 // | | | | blink | toggle | value | internally used BIOLOID_USER1_LED_PERIOD_L = 0x0101, @@ -268,7 +304,12 @@ typedef enum { BIOLOID_GYRO_FWD_FALL_THD = 0x017E, BIOLOID_GYRO_BWD_FALL_THD = 0x017F, BIOLOID_GYRO_LEFT_FALL_THD = 0x0180, - BOILOID_GYRO_RIGHT_FALL_THD = 0x0181 + BOILOID_GYRO_RIGHT_FALL_THD = 0x0181, + BIOLOID_WALK_CNTRL = 0x0182, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // current phase walking stop walking start walking + BIOLOID_WALK_STEP_FW_BW = 0x0183, + BIOLOID_WALK_STEP_LEFT_RIGHT = 0x0184, + BIOLOID_WALK_STEP_DIRECTION = 0x0185 } bioloid_registers; #define GPIO_BASE_ADDRESS 0x0100 @@ -291,7 +332,10 @@ typedef enum { #define MANAGER_BASE_ADDRESS 0x0128 #define MANAGER_MEM_LENGTH 82 -#define MANAGER_EEPROM_LENGTH 10 +#define MANAGER_EEPROM_BASE1 0x0006 +#define MANAGER_EEPROM_LENGTH1 10 +#define MANAGER_EEPROM_BASE2 0x0011 +#define MANAGER_EEPROM_LENGTH2 32 #define MANAGER_ENABLE 0x01 #define MANAGER_EN_BAL 0x02 #define MANAGER_EN_PWR 0x04 @@ -315,6 +359,15 @@ typedef enum { #define GYRO_EN_FALL_DET 0x04 #define GYRO_EN_FALL_DET_INT 0x08 +#define WALK_BASE_ADDRESS 0x0182 +#define WALK_MEM_LENGTH 4 +#define WALK_EEPROM_ADDRESS 0x0033 +#define WALK_EEPROM_LENGTH 19 +#define WALK_START 0x01 +#define WALK_STOP 0x02 +#define WALK_STATUS 0x10 +#define WALK_PHASE 0xC0 + #ifdef __cplusplus } #endif diff --git a/include/eeprom.h b/include/eeprom.h index bb184e86d8847e8f63129b9896b9163d7d99f8e0..68a136a6dd06dfe2cf74de8f0bda06b465338a17 100755 --- a/include/eeprom.h +++ b/include/eeprom.h @@ -83,7 +83,7 @@ extern "C" { #define PAGE_FULL ((uint8_t)0x80) /* Variables' number */ -#define NB_OF_VAR ((uint8_t)0x33) +#define NB_OF_VAR ((uint8_t)0x46) /* Exported types ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ diff --git a/include/walking.h b/include/walking.h new file mode 100755 index 0000000000000000000000000000000000000000..5beb8ce50e665d91d4d42af8f5a32850acdee6ac --- /dev/null +++ b/include/walking.h @@ -0,0 +1,30 @@ +#ifndef _WALKING_H +#define _WALKING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32f4xx.h" +#include "motion_manager.h" + +// public functions +void walking_init(uint16_t period_us); +inline void walking_set_period(uint16_t period_us); +inline uint16_t walking_get_period(void); +void walking_start(void); +void walking_stop(void); +uint8_t is_walking(void); + +// operation functions +uint8_t walking_in_range(unsigned short int address, unsigned short int length); +void walking_process_read_cmd(unsigned short int address,unsigned short int length,unsigned char *data); +void walking_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data); +// motion manager interface functions +void walking_process(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/bioloid_dyn_slave.c b/src/bioloid_dyn_slave.c index b2a0edfd9a9a3adb67f6326be462ce8eff90c42b..f58fbcf22696380e21ba63c4b288b13c95ce4e0d 100644 --- a/src/bioloid_dyn_slave.c +++ b/src/bioloid_dyn_slave.c @@ -53,23 +53,23 @@ unsigned char bioloid_on_write(unsigned short int address,unsigned short int len if(ram_in_range(BIOLOID_ID,address,length)) { dyn_slave_set_address(&bioloid_dyn_slave,data[BIOLOID_ID-address]); - ram_write_byte(BIOLOID_ID,data[BIOLOID_ID-address]); + ram_data[BIOLOID_ID]=data[BIOLOID_ID-address]; } if(ram_in_range(BIOLOID_BAUD_RATE,address,length)) { bioloid_comm_init.BaudRate=2000000/(data[BIOLOID_BAUD_RATE-address]+1); usart3_config(&bioloid_dyn_slave_comm,&bioloid_comm_init); - ram_write_byte(BIOLOID_BAUD_RATE,data[BIOLOID_BAUD_RATE-address]); + ram_data[BIOLOID_BAUD_RATE]=data[BIOLOID_BAUD_RATE-address]; } if(ram_in_range(BIOLOID_RETURN_DELAY_TIME,address,length)) { dyn_slave_set_return_delay(&bioloid_dyn_slave,data[BIOLOID_RETURN_DELAY_TIME-address]); - ram_write_byte(BIOLOID_RETURN_DELAY_TIME,data[BIOLOID_RETURN_DELAY_TIME-address]); + ram_data[BIOLOID_RETURN_DELAY_TIME]=data[BIOLOID_RETURN_DELAY_TIME-address]; } if(ram_in_range(BIOLOID_RETURN_LEVEL,address,length)) { dyn_slave_set_return_level(&bioloid_dyn_slave,data[BIOLOID_RETURN_LEVEL-address]); - ram_write_byte(BIOLOID_RETURN_LEVEL,data[BIOLOID_RETURN_LEVEL-address]); + ram_data[BIOLOID_RETURN_LEVEL]=data[BIOLOID_RETURN_LEVEL-address]; } // GPIO commands if(gpio_in_range(address,length)) @@ -98,7 +98,6 @@ unsigned char bioloid_on_write(unsigned short int address,unsigned short int len void bioloid_on_ping(void) { - gpio_toggle_led(RXD_LED); } /* interrupt service routines */ diff --git a/src/bioloid_gyro.c b/src/bioloid_gyro.c index 7c4d3dab8f5edfd6e95365d192e6fd4877bf81e0..a1fec04b0cca6c24956c16aca6ad065bd3608600 100644 --- a/src/bioloid_gyro.c +++ b/src/bioloid_gyro.c @@ -72,6 +72,10 @@ void gyro_process_read_cmd(unsigned short int address,unsigned short int length, void gyro_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data) { - + // gyro channels + if(ram_in_range(BIOLIOD_GYRO_FB_ADC_CH,address,length)) + ram_data[BIOLIOD_GYRO_FB_ADC_CH]=data[BIOLIOD_GYRO_FB_ADC_CH-address]; + if(ram_in_range(BIOLIOD_GYRO_LR_ADC_CH,address,length)) + ram_data[BIOLIOD_GYRO_LR_ADC_CH]=data[BIOLIOD_GYRO_LR_ADC_CH-address]; } diff --git a/src/bioloid_kinematics.c b/src/bioloid_kinematics.c new file mode 100755 index 0000000000000000000000000000000000000000..60a278934f42df8d4115a5d7706a4757486da541 --- /dev/null +++ b/src/bioloid_kinematics.c @@ -0,0 +1,82 @@ +#include "bioloid_kinematics.h" +#include "bioloid_math.h" +#include <math.h> + +uint8_t bioloid_leg_ik(float *out, float x, float y, float z, float a, float b, float c) +{ + TMatrix3D Tad, Tda, Tcd, Tdc, Tac; + TVector3D vec,orientation; + TPoint3D position; + float _Rac, _Acos, _Atan, _k, _l, _m, _n, _s, _c, _theta; + + vector3d_load(&orientation,a * 180.0 / PI, b * 180.0 / PI, c * 180.0 / PI); + point3d_load(&position,x, y, z - BIOLOID_LEG_LENGTH); + matrix3d_set_transform(&Tad,&position,&orientation); + + vec.x = x + Tad.coef[2] * BIOLOID_ANKLE_LENGTH; + vec.y = y + Tad.coef[6] * BIOLOID_ANKLE_LENGTH; + vec.z = (z - BIOLOID_LEG_LENGTH) + Tad.coef[10] * BIOLOID_ANKLE_LENGTH; + + // Get Knee + _Rac = vector3d_length(&vec); + _Acos = acos((_Rac * _Rac - BIOLOID_THIGH_LENGTH * BIOLOID_THIGH_LENGTH - BIOLOID_CALF_LENGTH * BIOLOID_CALF_LENGTH) / (2 * BIOLOID_THIGH_LENGTH * BIOLOID_CALF_LENGTH)); + if(isnan(_Acos) == 1) + return 0x00;; + *(out + 3) = _Acos; + + // Get Ankle Roll + Tda = Tad; + if(matrix3d_inverse(&Tda,&Tda) == 0x00) + return 0x00; + _k = sqrt(Tda.coef[7] * Tda.coef[7] + Tda.coef[11] * Tda.coef[11]); + _l = sqrt(Tda.coef[7] * Tda.coef[7] + (Tda.coef[11] - BIOLOID_ANKLE_LENGTH) * (Tda.coef[11] - BIOLOID_ANKLE_LENGTH)); + _m = (_k * _k - _l * _l - BIOLOID_ANKLE_LENGTH * BIOLOID_ANKLE_LENGTH) / (2 * _l * BIOLOID_ANKLE_LENGTH); + if(_m > 1.0) + _m = 1.0; + else if(_m < -1.0) + _m = -1.0; + _Acos = acos(_m); + if(isnan(_Acos) == 1) + return 0x00; + if(Tda.coef[7] < 0.0) + *(out + 5) = -_Acos; + else + *(out + 5) = _Acos; + // Get Hip Yaw + vector3d_load(&orientation,*(out + 5) * 180.0 / PI, 0, 0); + point3d_load(&position,0, 0, -BIOLOID_ANKLE_LENGTH); + matrix3d_set_transform(&Tcd,&position,&orientation); + Tdc = Tcd; + if(matrix3d_inverse(&Tdc,&Tdc) == 0x00) + return 0x00; + matrix3d_mult(&Tac,&Tad,&Tdc); + _Atan = atan2(-Tac.coef[1] , Tac.coef[5]); + if(isinf(_Atan) == 1) + return 0x00; + *(out) = _Atan; + + // Get Hip Roll + _Atan = atan2(Tac.coef[9], -Tac.coef[1] * sin(*(out)) + Tac.coef[5] * cos(*(out))); + if(isinf(_Atan) == 1) + return 0x00; + *(out + 1) = _Atan; + + // Get Hip Pitch and Ankle Pitch + _Atan = atan2(Tac.coef[2] * cos(*(out)) + Tac.coef[6] * sin(*(out)), Tac.coef[0] * cos(*(out)) + Tac.coef[4] * sin(*(out))); + if(isinf(_Atan) == 1) + return 0x00; + _theta = _Atan; + _k = sin(*(out + 3)) * BIOLOID_CALF_LENGTH; + _l = -BIOLOID_THIGH_LENGTH - cos(*(out + 3)) * BIOLOID_CALF_LENGTH; + _m = cos(*(out)) * vec.x + sin(*(out)) * vec.y; + _n = cos(*(out + 1)) * vec.z + sin(*(out)) * sin(*(out + 1)) * vec.x - cos(*(out)) * sin(*(out + 1)) * vec.y; + _s = (_k * _n + _l * _m) / (_k * _k + _l * _l); + _c = (_n - _k * _s) / _l; + _Atan = atan2(_s, _c); + if(isinf(_Atan) == 1) + return 0x00; + *(out + 2) = _Atan; + *(out + 4) = _theta - *(out + 3) - *(out + 2); + + return 0x01; +} diff --git a/src/bioloid_math.c b/src/bioloid_math.c new file mode 100755 index 0000000000000000000000000000000000000000..3f42bbdbb7b022ddf7933c847e030d927cf2d4dc --- /dev/null +++ b/src/bioloid_math.c @@ -0,0 +1,237 @@ +#include "bioloid_math.h" +#include <math.h> + +// point functions +void point3d_init(TPoint3D *point) +{ + point->x=0.0; + point->y=0.0; + point->z=0.0; +} + +void point3d_load(TPoint3D *point, float x, float y,float z) +{ + point->x=x; + point->y=y; + point->z=z; +} + +void point3d_copy(TPoint3D *point_dst, TPoint3D *point_src) +{ + point_dst->x=point_src->x; + point_dst->y=point_src->y; + point_dst->z=point_src->z; +} + +// vector functions +void vector3d_init(TVector3D *vector) +{ + vector->x=0.0; + vector->y=0.0; + vector->z=0.0; +} + +void vector3d_load(TVector3D *vector, float x, float y, float z) +{ + vector->x=x; + vector->y=y; + vector->z=z; +} + +void vector3d_copy(TVector3D *vector_dst, TVector3D *vector_src) +{ + vector_dst->x=vector_src->x; + vector_dst->y=vector_src->y; + vector_dst->z=vector_src->z; +} + +float vector3d_length(TVector3D *vector) +{ + return sqrt(vector->x*vector->x + vector->y*vector->y + vector->z*vector->z); +} + +// matrix functions +void matrix3d_init(TMatrix3D *matrix) +{ + matrix3d_identity(matrix); +} + +void matrix3d_copy(TMatrix3D *matrix_dst, TMatrix3D *matrix_src) +{ + matrix_dst->coef[m00]=matrix_src->coef[m00]; + matrix_dst->coef[m01]=matrix_src->coef[m01]; + matrix_dst->coef[m02]=matrix_src->coef[m02]; + matrix_dst->coef[m03]=matrix_src->coef[m03]; + matrix_dst->coef[m10]=matrix_src->coef[m10]; + matrix_dst->coef[m11]=matrix_src->coef[m11]; + matrix_dst->coef[m12]=matrix_src->coef[m12]; + matrix_dst->coef[m13]=matrix_src->coef[m13]; + matrix_dst->coef[m20]=matrix_src->coef[m20]; + matrix_dst->coef[m21]=matrix_src->coef[m21]; + matrix_dst->coef[m22]=matrix_src->coef[m22]; + matrix_dst->coef[m23]=matrix_src->coef[m23]; + matrix_dst->coef[m30]=matrix_src->coef[m30]; + matrix_dst->coef[m31]=matrix_src->coef[m31]; + matrix_dst->coef[m32]=matrix_src->coef[m32]; + matrix_dst->coef[m33]=matrix_src->coef[m33]; +} + +void matrix3d_zero(TMatrix3D *matrix) +{ + matrix->coef[m00]=0.0; + matrix->coef[m01]=0.0; + matrix->coef[m02]=0.0; + matrix->coef[m03]=0.0; + matrix->coef[m10]=0.0; + matrix->coef[m11]=0.0; + matrix->coef[m12]=0.0; + matrix->coef[m13]=0.0; + matrix->coef[m20]=0.0; + matrix->coef[m21]=0.0; + matrix->coef[m22]=0.0; + matrix->coef[m23]=0.0; + matrix->coef[m30]=0.0; + matrix->coef[m31]=0.0; + matrix->coef[m32]=0.0; + matrix->coef[m33]=0.0; +} + +void matrix3d_identity(TMatrix3D *matrix) +{ + matrix->coef[m00]=1.0; + matrix->coef[m01]=0.0; + matrix->coef[m02]=0.0; + matrix->coef[m03]=0.0; + matrix->coef[m10]=0.0; + matrix->coef[m11]=1.0; + matrix->coef[m12]=0.0; + matrix->coef[m13]=0.0; + matrix->coef[m20]=0.0; + matrix->coef[m21]=0.0; + matrix->coef[m22]=1.0; + matrix->coef[m23]=0.0; + matrix->coef[m30]=0.0; + matrix->coef[m31]=0.0; + matrix->coef[m32]=0.0; + matrix->coef[m33]=1.0; +} + +uint8_t matrix3d_inverse(TMatrix3D *org, TMatrix3D *inv) +{ + TMatrix3D src, tmp; + float det; + uint8_t i; + + /* transpose matrix */ + for (i = 0; i < 4; i++) + { + src.coef[i] = org->coef[i*4]; + src.coef[i + 4] = org->coef[i*4 + 1]; + src.coef[i + 8] = org->coef[i*4 + 2]; + src.coef[i + 12] = org->coef[i*4 + 3]; + } + + /* calculate pairs for first 8 elements (cofactors) */ + tmp.coef[0] = src.coef[10] * src.coef[15]; + tmp.coef[1] = src.coef[11] * src.coef[14]; + tmp.coef[2] = src.coef[9] * src.coef[15]; + tmp.coef[3] = src.coef[11] * src.coef[13]; + tmp.coef[4] = src.coef[9] * src.coef[14]; + tmp.coef[5] = src.coef[10] * src.coef[13]; + tmp.coef[6] = src.coef[8] * src.coef[15]; + tmp.coef[7] = src.coef[11] * src.coef[12]; + tmp.coef[8] = src.coef[8] * src.coef[14]; + tmp.coef[9] = src.coef[10] * src.coef[12]; + tmp.coef[10] = src.coef[8] * src.coef[13]; + tmp.coef[11] = src.coef[9] * src.coef[12]; + /* calculate first 8 elements (cofactors) */ + inv->coef[0] = (tmp.coef[0]*src.coef[5] + tmp.coef[3]*src.coef[6] + tmp.coef[4]*src.coef[7]) - (tmp.coef[1]*src.coef[5] + tmp.coef[2]*src.coef[6] + tmp.coef[5]*src.coef[7]); + inv->coef[1] = (tmp.coef[1]*src.coef[4] + tmp.coef[6]*src.coef[6] + tmp.coef[9]*src.coef[7]) - (tmp.coef[0]*src.coef[4] + tmp.coef[7]*src.coef[6] + tmp.coef[8]*src.coef[7]); + inv->coef[2] = (tmp.coef[2]*src.coef[4] + tmp.coef[7]*src.coef[5] + tmp.coef[10]*src.coef[7]) - (tmp.coef[3]*src.coef[4] + tmp.coef[6]*src.coef[5] + tmp.coef[11]*src.coef[7]); + inv->coef[3] = (tmp.coef[5]*src.coef[4] + tmp.coef[8]*src.coef[5] + tmp.coef[11]*src.coef[6]) - (tmp.coef[4]*src.coef[4] + tmp.coef[9]*src.coef[5] + tmp.coef[10]*src.coef[6]); + inv->coef[4] = (tmp.coef[1]*src.coef[1] + tmp.coef[2]*src.coef[2] + tmp.coef[5]*src.coef[3]) - (tmp.coef[0]*src.coef[1] + tmp.coef[3]*src.coef[2] + tmp.coef[4]*src.coef[3]); + inv->coef[5] = (tmp.coef[0]*src.coef[0] + tmp.coef[7]*src.coef[2] + tmp.coef[8]*src.coef[3]) - (tmp.coef[1]*src.coef[0] + tmp.coef[6]*src.coef[2] + tmp.coef[9]*src.coef[3]); + inv->coef[6] = (tmp.coef[3]*src.coef[0] + tmp.coef[6]*src.coef[1] + tmp.coef[11]*src.coef[3]) - (tmp.coef[2]*src.coef[0] + tmp.coef[7]*src.coef[1] + tmp.coef[10]*src.coef[3]); + inv->coef[7] = (tmp.coef[4]*src.coef[0] + tmp.coef[9]*src.coef[1] + tmp.coef[10]*src.coef[2]) - (tmp.coef[5]*src.coef[0] + tmp.coef[8]*src.coef[1] + tmp.coef[11]*src.coef[2]); + /* calculate pairs for second 8 elements (cofactors) */ + tmp.coef[0] = src.coef[2]*src.coef[7]; + tmp.coef[1] = src.coef[3]*src.coef[6]; + tmp.coef[2] = src.coef[1]*src.coef[7]; + tmp.coef[3] = src.coef[3]*src.coef[5]; + tmp.coef[4] = src.coef[1]*src.coef[6]; + tmp.coef[5] = src.coef[2]*src.coef[5]; + //Streaming SIMD Extensions - Inverse of 4x4 Matrix 8 + tmp.coef[6] = src.coef[0]*src.coef[7]; + tmp.coef[7] = src.coef[3]*src.coef[4]; + tmp.coef[8] = src.coef[0]*src.coef[6]; + tmp.coef[9] = src.coef[2]*src.coef[4]; + tmp.coef[10] = src.coef[0]*src.coef[5]; + tmp.coef[11] = src.coef[1]*src.coef[4]; + /* calculate second 8 elements (cofactors) */ + inv->coef[8] = (tmp.coef[0]*src.coef[13] + tmp.coef[3]*src.coef[14] + tmp.coef[4]*src.coef[15]) - (tmp.coef[1]*src.coef[13] + tmp.coef[2]*src.coef[14] + tmp.coef[5]*src.coef[15]); + inv->coef[9] = (tmp.coef[1]*src.coef[12] + tmp.coef[6]*src.coef[14] + tmp.coef[9]*src.coef[15]) - (tmp.coef[0]*src.coef[12] + tmp.coef[7]*src.coef[14] + tmp.coef[8]*src.coef[15]); + inv->coef[10] = (tmp.coef[2]*src.coef[12] + tmp.coef[7]*src.coef[13] + tmp.coef[10]*src.coef[15]) - (tmp.coef[3]*src.coef[12] + tmp.coef[6]*src.coef[13] + tmp.coef[11]*src.coef[15]); + inv->coef[11] = (tmp.coef[5]*src.coef[12] + tmp.coef[8]*src.coef[13] + tmp.coef[11]*src.coef[14]) - (tmp.coef[4]*src.coef[12] + tmp.coef[9]*src.coef[13] + tmp.coef[10]*src.coef[14]); + inv->coef[12] = (tmp.coef[2]*src.coef[10] + tmp.coef[5]*src.coef[11] + tmp.coef[1]*src.coef[9]) - (tmp.coef[4]*src.coef[11] + tmp.coef[0]*src.coef[9] + tmp.coef[3]*src.coef[10]); + inv->coef[13] = (tmp.coef[8]*src.coef[11] + tmp.coef[0]*src.coef[8] + tmp.coef[7]*src.coef[10]) - (tmp.coef[6]*src.coef[10] + tmp.coef[9]*src.coef[11] + tmp.coef[1]*src.coef[8]); + inv->coef[14] = (tmp.coef[6]*src.coef[9] + tmp.coef[11]*src.coef[11] + tmp.coef[3]*src.coef[8]) - (tmp.coef[10]*src.coef[11] + tmp.coef[2]*src.coef[8] + tmp.coef[7]*src.coef[9]); + inv->coef[15] = (tmp.coef[10]*src.coef[10] + tmp.coef[4]*src.coef[8] + tmp.coef[9]*src.coef[9]) - (tmp.coef[8]*src.coef[9] + tmp.coef[11]*src.coef[10] + tmp.coef[5]*src.coef[8]); + /* calculate determinant */ + det = src.coef[0]*inv->coef[0] + src.coef[1]*inv->coef[1] + src.coef[2]*inv->coef[2] + src.coef[3]*inv->coef[3]; + /* calculate matrix inverse */ + if (det == 0) + { + det = 0; + return 0x00; + } + else + { + det = 1 / det; + } + + for (i = 0; i < 16; i++) + inv->coef[i]*=det; + + return 0x01; +} + +void matrix3d_set_transform(TMatrix3D *matrix, TPoint3D *point, TVector3D *vector) +{ + float Cx = cos(vector->x * PI / 180.0); + float Cy = cos(vector->y * PI / 180.0); + float Cz = cos(vector->z * PI / 180.0); + float Sx = sin(vector->x * PI / 180.0); + float Sy = sin(vector->y * PI / 180.0); + float Sz = sin(vector->z * PI / 180.0); + + matrix3d_identity(matrix); + matrix->coef[0] = Cz * Cy; + matrix->coef[1] = Cz * Sy * Sx - Sz * Cx; + matrix->coef[2] = Cz * Sy * Cx + Sz * Sx; + matrix->coef[3] = point->x; + matrix->coef[4] = Sz * Cy; + matrix->coef[5] = Sz * Sy * Sx + Cz * Cx; + matrix->coef[6] = Sz * Sy * Cx - Cz * Sx; + matrix->coef[7] = point->y; + matrix->coef[8] = -Sy; + matrix->coef[9] = Cy * Sx; + matrix->coef[10] = Cy * Cx; + matrix->coef[11] = point->z; +} + +void matrix3d_mult(TMatrix3D *dst,TMatrix3D *a,TMatrix3D *b) +{ + uint8_t i,j,c; + + matrix3d_zero(dst); + for(j = 0; j < 4; j++) + { + for(i = 0; i < 4; i++) + { + for(c = 0; c < 4; c++) + { + dst->coef[j*4+i] += a->coef[j*4+c] * b->coef[c*4+i]; + } + } + } +} diff --git a/src/eeprom.c b/src/eeprom.c index 5d965d6f0befaadad4f5aee206c194d73f8e8aa4..48aa5e5c3f1ae341c3775a95db66160ffba1f491 100755 --- a/src/eeprom.c +++ b/src/eeprom.c @@ -46,7 +46,6 @@ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define EEPROM_SIZE 0x20 #define DEFAULT_DEVICE_MODEL 0x7300 #define DEFAULT_FIRMWARE_VERSION 0x0001 #define DEFAULT_DEVICE_ID 0x0002 @@ -60,38 +59,56 @@ #define DEFAULT_GYRO_FB_ADC_CH (uint16_t)ADC_CH1 #define DEFAULT_GYRO_LR_ADC_CH (uint16_t)ADC_CH2 #define DEFAULT_RETURN_LEVEL 0x0002 -#define DEFAULT_SERVO0_OFFSET 0x0000 -#define DEFAULT_SERVO1_OFFSET 0x0000 -#define DEFAULT_SERVO2_OFFSET 0x0000 -#define DEFAULT_SERVO3_OFFSET 0x0000 -#define DEFAULT_SERVO4_OFFSET 0x0000 -#define DEFAULT_SERVO5_OFFSET 0x0000 -#define DEFAULT_SERVO6_OFFSET 0x0000 -#define DEFAULT_SERVO7_OFFSET 0x0000 -#define DEFAULT_SERVO8_OFFSET 0x0000 -#define DEFAULT_SERVO9_OFFSET 0x0000 -#define DEFAULT_SERVO10_OFFSET 0x0000 -#define DEFAULT_SERVO11_OFFSET 0x0000 -#define DEFAULT_SERVO12_OFFSET 0x0000 -#define DEFAULT_SERVO13_OFFSET 0x0000 -#define DEFAULT_SERVO14_OFFSET 0x0000 -#define DEFAULT_SERVO15_OFFSET 0x0000 -#define DEFAULT_SERVO16_OFFSET 0x0000 -#define DEFAULT_SERVO17_OFFSET 0x0000 -#define DEFAULT_SERVO18_OFFSET 0x0000 -#define DEFAULT_SERVO19_OFFSET 0x0000 -#define DEFAULT_SERVO20_OFFSET 0x0000 -#define DEFAULT_SERVO21_OFFSET 0x0000 -#define DEFAULT_SERVO22_OFFSET 0x0000 -#define DEFAULT_SERVO23_OFFSET 0x0000 -#define DEFAULT_SERVO24_OFFSET 0x0000 -#define DEFAULT_SERVO25_OFFSET 0x0000 -#define DEFAULT_SERVO26_OFFSET 0x0000 -#define DEFAULT_SERVO27_OFFSET 0x0000 -#define DEFAULT_SERVO28_OFFSET 0x0000 -#define DEFAULT_SERVO29_OFFSET 0x0000 -#define DEFAULT_SERVO30_OFFSET 0x0000 -#define DEFAULT_SERVO31_OFFSET 0x0000 +#define DEFAULT_SERVO0_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO1_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO2_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO3_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO4_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO5_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO6_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO7_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO8_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO9_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO10_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO11_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO12_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO13_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO14_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO15_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO16_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO17_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO18_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO19_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO20_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO21_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO22_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO23_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO24_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO25_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO26_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO27_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO28_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO29_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO30_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_SERVO31_OFFSET 0x0000 // 0 in fixed point format 4 (1+3) | 4 +#define DEFAULT_WALK_X_OFFSET 0xFFF6 // -10 mm +#define DEFAULT_WALK_Y_OFFSET 0x0005 // 5 mm +#define DEFAULT_WALK_Z_OFFSET 0x0014 // 20 mm +#define DEFAULT_WALK_ROLL_OFFSET 0x0000 // 0 degrees in fixed point format 5 (1+4) | 3 +#define DEFAULT_WALK_PITCH_OFFSET 0x0000 // 0 degrees in fixed point format 5 (1+4) | 3 +#define DEFAULT_WALK_YAW_OFFSET 0x0000 // 0 degrees in fixed point format 5 (1+4) | 3 +#define DEFAULT_WALK_HIP_PITCH_OFF 0x0000 // 0 degrees in fixed point format 6 (1+5) | 10 +#define DEFAULT_WALK_PERIOD_TIME 0x0258 // 600 ms +#define DEFAULT_WALK_DSP_RATIO 0x0019 // 0.1 in fixed point format 0 | 8 +#define DEFAULT_WALK_STEP_FW_BW_RATIO 0x004C // 0.3 in fixed point format 0 | 8 +#define DEFAULT_WALK_FOOT_HEIGHT 0x0028 // 40 mm +#define DEFAULT_WALK_SWING_RIGHT_LEFT 0x0014 // 20 mm +#define DEFAULT_WALK_SWING_TOP_DOWN 0x0005 // 5 mm +#define DEFAULT_WALK_PELVIS_OFFSET 0x0018 // 3 degrees in fixed point format 5 (1+4) | 3 +#define DEFAULT_WALK_ARM_SWING_GAIN 0x0030 // 1.5 in fixed point format 3 | 5 +#define DEFAULT_WALK_MAX_VEL 0x0016 // 20 mm/s +#define DEFAULT_WALK_MAX_ROT_VEL 0x0008 // 8 degrees/s in fixed point format 5 | 3 + /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ @@ -150,7 +167,26 @@ uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE, DEFAULT_SERVO30_OFFSET, MM_SERVO30_OFFSET, DEFAULT_SERVO31_OFFSET, MM_SERVO31_OFFSET, DEFAULT_GYRO_FB_ADC_CH, GYRO_FB_ADC_CH_OFFSET, - DEFAULT_GYRO_LR_ADC_CH, GYRO_LR_ADC_CH_OFFSET}; + DEFAULT_GYRO_LR_ADC_CH, GYRO_LR_ADC_CH_OFFSET, + DEFAULT_WALK_X_OFFSET, WALK_X_OFFSET, + DEFAULT_WALK_Y_OFFSET, WALK_Y_OFFSET, + DEFAULT_WALK_Z_OFFSET, WALK_Z_OFFSET, + DEFAULT_WALK_ROLL_OFFSET, WALK_ROLL_OFFSET, + DEFAULT_WALK_PITCH_OFFSET, WALK_PITCH_OFFSET, + DEFAULT_WALK_YAW_OFFSET, WALK_YAW_OFFSET, + DEFAULT_WALK_HIP_PITCH_OFF&0xFF, WALK_HIP_PITCH_OFF, + DEFAULT_WALK_HIP_PITCH_OFF>>8, WALK_HIP_PITCH_OFF+1, + DEFAULT_WALK_PERIOD_TIME&0xFF, WALK_PERIOD_TIME, + DEFAULT_WALK_PERIOD_TIME>>8, WALK_PERIOD_TIME+1, + DEFAULT_WALK_DSP_RATIO, WALK_DSP_RATIO, + DEFAULT_WALK_STEP_FW_BW_RATIO, WALK_STEP_FW_BW_RATIO, + DEFAULT_WALK_FOOT_HEIGHT, WALK_FOOT_HEIGHT, + DEFAULT_WALK_SWING_RIGHT_LEFT, WALK_SWING_RIGHT_LEFT, + DEFAULT_WALK_SWING_TOP_DOWN, WALK_SWING_TOP_DOWN, + DEFAULT_WALK_PELVIS_OFFSET, WALK_PELVIS_OFFSET, + DEFAULT_WALK_ARM_SWING_GAIN, WALK_ARM_SWING_GAIN, + DEFAULT_WALK_MAX_VEL, WALK_MAX_VEL, + DEFAULT_WALK_MAX_ROT_VEL, WALK_MAX_ROT_VEL}; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ diff --git a/src/motion_manager.c b/src/motion_manager.c index 97b7cf0da77fdb593f1c9fc11a82f5adc83622fc..ba2e387a06798ce70b4e8c05a9c316e304ca6a5b 100644 --- a/src/motion_manager.c +++ b/src/motion_manager.c @@ -5,7 +5,7 @@ #include "action.h" #include "adc_dma.h" #include "bioloid_gyro.h" -#include "gpio.h" +#include "walking.h" #define MANAGER_TIMER TIM3 #define ENABLE_MANAGER_TIMER_CLK __HAL_RCC_TIM3_CLK_ENABLE() @@ -99,14 +99,11 @@ void manager_get_target_position(void) { if(manager_servos[i].enabled && manager_servos[i].model!=0x0000)// servo is enabled and present { - if(manager_servos[i].module==MM_ACTION) - { - manager_servos[i].current_angle=((manager_current_angles[i]>>9)+manager_balance_offset[i]+manager_offset[i]); - //>>16 from the action codification, <<7 from the manager codification - manager_servos[i].current_value=manager_angle_to_value(i,manager_servos[i].current_angle); - ram_data[BIOLOID_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF); - ram_data[BIOLOID_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8); - } + manager_servos[i].current_angle=((manager_current_angles[i]>>9)+manager_balance_offset[i]+manager_offset[i]); + //>>16 from the action codification, <<7 from the manager codification + manager_servos[i].current_value=manager_angle_to_value(i,manager_servos[i].current_angle); + ram_data[BIOLOID_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF); + ram_data[BIOLOID_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8); } } } @@ -161,7 +158,7 @@ void MANAGER_TIMER_IRQHandler(void) // call the joint motion process // joint_motion_process(); // call the walking process - // walking_process(); + walking_process(); // balance the robot manager_balance(); // get the target angles from all modules @@ -329,10 +326,10 @@ void manager_init(uint16_t period_us) manager_set_offset(i,(signed char)ram_data[BIOLOID_MM_SERVO0_OFFSET+i]); } manager_balance_enabled=0x00; - gpio_set_led(TXD_LED); /* initialize action module */ action_init(period_us); + walking_init(period_us); } uint16_t manager_get_period(void) @@ -351,6 +348,8 @@ void manager_set_period(uint16_t period_us) manager_motion_period_us=period_us; ram_data[BIOLOID_MM_PERIOD_L]=period_us&0x00FF; ram_data[BIOLOID_MM_PERIOD_H]=(period_us&0xFF00)>>8; + action_set_period(period_us); + walking_set_period(period_us); } inline void manager_enable(void) @@ -483,8 +482,8 @@ inline int16_t manager_get_ccw_angle_limit(uint8_t servo_id) uint8_t manager_in_range(unsigned short int address, unsigned short int length) { if(ram_in_window(MANAGER_BASE_ADDRESS,MANAGER_MEM_LENGTH,address,length) || - ram_in_window(BIOLOID_MM_PERIOD_L,10,address,length) || - ram_in_window(BIOLOID_MM_SERVO0_OFFSET,MANAGER_MAX_NUM_SERVOS,address,length)) + ram_in_window(MANAGER_EEPROM_BASE1,MANAGER_EEPROM_LENGTH1,address,length) || + ram_in_window(MANAGER_EEPROM_BASE2,MANAGER_EEPROM_LENGTH2,address,length)) return 0x01; else return 0x00; @@ -535,4 +534,8 @@ void manager_process_write_cmd(unsigned short int address,unsigned short int len else bioloid_dyn_master_servos_disable_power(); } + // balance gains + for(i=MM_BAL_KNEE_GAIN_OFFSET;i<=MM_BAL_HIP_ROLL_GAIN_OFFSET+1;i++) + if(ram_in_range(i,address,length)) + ram_data[i]=data[i-address]; } diff --git a/src/ram.c b/src/ram.c index 45069ef7f06a94cc647195685d5b76ea480a55bf..34142288c21d200e51380b6f2ece9eb61c3e1f03 100644 --- a/src/ram.c +++ b/src/ram.c @@ -53,6 +53,44 @@ void ram_init(void) ram_data[GYRO_FB_ADC_CH_OFFSET]=(uint8_t)(eeprom_data&0x00FF); if(EE_ReadVariable(GYRO_LR_ADC_CH_OFFSET,&eeprom_data)==0) ram_data[GYRO_LR_ADC_CH_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_X_OFFSET,&eeprom_data)==0) + ram_data[WALK_X_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_Y_OFFSET,&eeprom_data)==0) + ram_data[WALK_Y_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_Z_OFFSET,&eeprom_data)==0) + ram_data[WALK_Z_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_ROLL_OFFSET,&eeprom_data)==0) + ram_data[WALK_ROLL_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_PITCH_OFFSET,&eeprom_data)==0) + ram_data[WALK_PITCH_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_YAW_OFFSET,&eeprom_data)==0) + ram_data[WALK_YAW_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_HIP_PITCH_OFF,&eeprom_data)==0) + ram_data[WALK_HIP_PITCH_OFF]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_HIP_PITCH_OFF+1,&eeprom_data)==0) + ram_data[WALK_HIP_PITCH_OFF+1]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_PERIOD_TIME,&eeprom_data)==0) + ram_data[WALK_PERIOD_TIME]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_PERIOD_TIME+1,&eeprom_data)==0) + ram_data[WALK_PERIOD_TIME+1]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_DSP_RATIO,&eeprom_data)==0) + ram_data[WALK_DSP_RATIO]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_STEP_FW_BW_RATIO,&eeprom_data)==0) + ram_data[WALK_STEP_FW_BW_RATIO]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_FOOT_HEIGHT,&eeprom_data)==0) + ram_data[WALK_FOOT_HEIGHT]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_SWING_RIGHT_LEFT,&eeprom_data)==0) + ram_data[WALK_SWING_RIGHT_LEFT]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_SWING_TOP_DOWN,&eeprom_data)==0) + ram_data[WALK_SWING_TOP_DOWN]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_PELVIS_OFFSET,&eeprom_data)==0) + ram_data[WALK_PELVIS_OFFSET]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_ARM_SWING_GAIN,&eeprom_data)==0) + ram_data[WALK_ARM_SWING_GAIN]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_MAX_VEL,&eeprom_data)==0) + ram_data[WALK_MAX_VEL]=(uint8_t)(eeprom_data&0x00FF); + if(EE_ReadVariable(WALK_MAX_ROT_VEL,&eeprom_data)==0) + ram_data[WALK_MAX_ROT_VEL]=(uint8_t)(eeprom_data&0x00FF); } inline void ram_read_byte(uint16_t address,uint8_t *data) diff --git a/src/walking.c b/src/walking.c new file mode 100755 index 0000000000000000000000000000000000000000..86f808d9813a098abfe2a2c252f40892d4faaed1 --- /dev/null +++ b/src/walking.c @@ -0,0 +1,506 @@ +#include "walking.h" +#include "bioloid_kinematics.h" +#include "bioloid_math.h" +#include "ram.h" +#include <math.h> + +enum {PHASE0=0x00,PHASE1=0x40,PHASE2=0x80,PHASE3=0xC0}; + +// Walking control +float X_MOVE_AMPLITUDE=0.0;//mm +float Y_MOVE_AMPLITUDE=0.0;//mm +float A_MOVE_AMPLITUDE=0.0;//degrees +uint8_t A_MOVE_AIM_ON=0x00; + +// internal motion variables +float m_X_Swap_Phase_Shift; +float m_X_Swap_Amplitude; +float m_X_Swap_Amplitude_Shift; +float m_X_Move_Phase_Shift; +float m_X_Move_Amplitude; +float m_X_Move_Amplitude_Shift; +float m_Y_Swap_Phase_Shift; +float m_Y_Swap_Amplitude; +float m_Y_Swap_Amplitude_Shift; +float m_Y_Move_Phase_Shift; +float m_Y_Move_Amplitude; +float m_Y_Move_Amplitude_Shift; +float m_Z_Swap_Phase_Shift; +float m_Z_Swap_Amplitude; +float m_Z_Swap_Amplitude_Shift; +float m_Z_Move_Phase_Shift; +float m_Z_Move_Amplitude; +float m_Z_Move_Amplitude_Shift; +float m_A_Move_Phase_Shift; +float m_A_Move_Amplitude; +float m_A_Move_Amplitude_Shift; + +// internal offset variables +float m_Hip_Pitch_Offset; +float m_Pelvis_Offset; +float m_Pelvis_Swing; +float m_Arm_Swing_Gain; +float m_X_Offset; +float m_Y_Offset; +float m_Z_Offset; +float m_R_Offset; +float m_P_Offset; +float m_A_Offset; + +// internal time variables +float m_Time; +float m_PeriodTime; +float m_X_Swap_PeriodTime; +float m_X_Move_PeriodTime; +float m_Y_Swap_PeriodTime; +float m_Y_Move_PeriodTime; +float m_Z_Swap_PeriodTime; +float m_Z_Move_PeriodTime; +float m_A_Move_PeriodTime; +float m_SSP_Time_Start_L; +float m_SSP_Time_End_L; +float m_SSP_Time_Start_R; +float m_SSP_Time_End_R; +float m_Phase_Time1; +float m_Phase_Time2; +float m_Phase_Time3; + +// control variables +uint8_t m_Ctrl_Running; +float walking_period; + +// private functions +inline float wsin(float time, float period, float period_shift, float mag, float mag_shift) +{ + return mag*sin(((2.0*PI*time)/period)-period_shift)+mag_shift; +} + +void update_param_time() +{ + float m_SSP_Ratio; + float m_SSP_Time; + + m_PeriodTime=ram_data[BIOLOID_WALK_PERIOD_TIME_L]+ram_data[BIOLOID_WALK_PERIOD_TIME_H]; + m_SSP_Ratio=1.0-((float)ram_data[BIOLOID_WALK_DSP_RATIO])/256.0; + + m_SSP_Time=m_PeriodTime*m_SSP_Ratio; + + m_X_Swap_PeriodTime=m_PeriodTime/2.0; + m_X_Move_PeriodTime=m_SSP_Time; + m_Y_Swap_PeriodTime=m_PeriodTime; + m_Y_Move_PeriodTime=m_SSP_Time; + m_Z_Swap_PeriodTime=m_PeriodTime/2.0; + m_Z_Move_PeriodTime=m_SSP_Time/2.0; + m_A_Move_PeriodTime=m_SSP_Time; + + m_SSP_Time_Start_L=(1-m_SSP_Ratio)*m_PeriodTime/4.0; + m_SSP_Time_End_L=(1+m_SSP_Ratio)*m_PeriodTime/4.0; + m_SSP_Time_Start_R=(3-m_SSP_Ratio)*m_PeriodTime/4.0; + m_SSP_Time_End_R=(3+m_SSP_Ratio)*m_PeriodTime/4.0; + + m_Phase_Time1=(m_SSP_Time_End_L+m_SSP_Time_Start_L)/2.0; + m_Phase_Time2=(m_SSP_Time_Start_R+m_SSP_Time_End_L)/2.0; + m_Phase_Time3=(m_SSP_Time_End_R+m_SSP_Time_Start_R)/2.0; + + // m_pelvis_offset and m_pelvis_Swing in degrees + m_Pelvis_Offset=((float)ram_data[BIOLOID_WALK_PELVIS_OFFSET])/8.0; + m_Pelvis_Swing=m_Pelvis_Offset*0.35; + m_Arm_Swing_Gain=((float)ram_data[BIOLOID_WALK_ARM_SWING_GAIN])/32.0; +} + +void update_param_move() +{ + static float current_x_amplitude=0; + static float current_y_amplitude=0; + static float current_a_amplitude=0; + + // change longitudinal and transversal velocities to get to the target ones + if(current_x_amplitude<X_MOVE_AMPLITUDE) + { + current_x_amplitude+=(((float)ram_data[BIOLOID_WALK_MAX_VEL])*m_PeriodTime)/1000.0; + if(current_x_amplitude>X_MOVE_AMPLITUDE) + current_x_amplitude=X_MOVE_AMPLITUDE; + } + else if(current_x_amplitude>X_MOVE_AMPLITUDE) + { + current_x_amplitude-=(((float)ram_data[BIOLOID_WALK_MAX_VEL])*m_PeriodTime)/1000.0; + if(current_x_amplitude<X_MOVE_AMPLITUDE) + current_x_amplitude=X_MOVE_AMPLITUDE; + } + m_X_Move_Amplitude=current_x_amplitude; + m_X_Swap_Amplitude=current_x_amplitude*((float)ram_data[BIOLOID_WALK_STEP_FW_BW_RATIO])/256.0; + + // Right/Left + if(current_y_amplitude<Y_MOVE_AMPLITUDE) + { + current_y_amplitude+=(((float)ram_data[BIOLOID_WALK_MAX_VEL])*m_PeriodTime)/1000.0; + if(current_y_amplitude>Y_MOVE_AMPLITUDE) + current_y_amplitude=Y_MOVE_AMPLITUDE; + } + else if(current_y_amplitude>Y_MOVE_AMPLITUDE) + { + current_y_amplitude-=(((float)ram_data[BIOLOID_WALK_MAX_VEL])*m_PeriodTime)/1000.0; + if(current_y_amplitude<Y_MOVE_AMPLITUDE) + current_y_amplitude=Y_MOVE_AMPLITUDE; + } + m_Y_Move_Amplitude=current_y_amplitude/2.0; + if(m_Y_Move_Amplitude>0) + m_Y_Move_Amplitude_Shift=m_Y_Move_Amplitude; + else + m_Y_Move_Amplitude_Shift=-m_Y_Move_Amplitude; + m_Y_Swap_Amplitude=((float)ram_data[BIOLOID_WALK_SWING_RIGHT_LEFT])+m_Y_Move_Amplitude_Shift*0.04; + + m_Z_Move_Amplitude=((float)ram_data[BIOLOID_WALK_FOOT_HEIGHT])/2.0; + m_Z_Move_Amplitude_Shift=m_Z_Move_Amplitude / 2.0; + m_Z_Swap_Amplitude=((float)ram_data[BIOLOID_WALK_SWING_TOP_DOWN]); + m_Z_Swap_Amplitude_Shift=m_Z_Swap_Amplitude; + + // Direction + if(current_a_amplitude<A_MOVE_AMPLITUDE) + { + current_a_amplitude+=(((float)ram_data[BIOLOID_WALK_MAX_ROT_VEL])*m_PeriodTime)/8000.0; + if(current_a_amplitude>A_MOVE_AMPLITUDE) + current_a_amplitude=A_MOVE_AMPLITUDE; + } + else if(current_a_amplitude>A_MOVE_AMPLITUDE) + { + current_a_amplitude-=(((float)ram_data[BIOLOID_WALK_MAX_ROT_VEL])*m_PeriodTime)/8000.0; + if(current_a_amplitude<A_MOVE_AMPLITUDE) + current_a_amplitude=A_MOVE_AMPLITUDE; + } + + if(A_MOVE_AIM_ON==0x00) + { + m_A_Move_Amplitude=current_a_amplitude*PI/180.0/2.0; + if(m_A_Move_Amplitude>0) + m_A_Move_Amplitude_Shift=m_A_Move_Amplitude; + else + m_A_Move_Amplitude_Shift=-m_A_Move_Amplitude; + } + else + { + m_A_Move_Amplitude=-current_a_amplitude*PI/180.0/2.0; + if(m_A_Move_Amplitude>0) + m_A_Move_Amplitude_Shift=-m_A_Move_Amplitude; + else + m_A_Move_Amplitude_Shift=m_A_Move_Amplitude; + } +} + +void update_param_balance() +{ + m_X_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_X_OFFSET])); + m_Y_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_Y_OFFSET])); + m_Z_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_Z_OFFSET])); + m_R_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_ROLL_OFFSET]))*PI/1440.0;// (r_offset/8)*(pi/180) + m_P_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_PITCH_OFFSET]))*PI/1440.0;// (p_offset/8)*(pi/180) + m_A_Offset = ((float)((int8_t)ram_data[BIOLOID_WALK_YAW_OFFSET]))*PI/1440.0;// (a_offset/8)*(pi/180) + m_Hip_Pitch_Offset = ((float)((int16_t)(ram_data[BIOLOID_WALK_HIP_PITCH_OFF_L]+(ram_data[BIOLOID_WALK_HIP_PITCH_OFF_L]<<8))))/1024.0; +} + +// public functions +void walking_init(uint16_t period_us) +{ + // initialize the internal motion variables + m_X_Swap_Phase_Shift=PI; + m_X_Swap_Amplitude_Shift=0.0; + m_X_Move_Phase_Shift=PI/2.0; + m_X_Move_Amplitude=0.0; + m_X_Move_Amplitude_Shift=0.0; + m_Y_Swap_Phase_Shift=0.0; + m_Y_Swap_Amplitude_Shift=0.0; + m_Y_Move_Phase_Shift=PI/2.0; + m_Z_Swap_Phase_Shift=PI*3.0/2.0; + m_Z_Move_Phase_Shift=PI/2.0; + m_A_Move_Phase_Shift=PI/2.0; + + // initialize internal control variables + m_Time=0; + walking_period=((float)period_us)/1000.0; + m_Ctrl_Running=0x00; + + update_param_time(); + update_param_move(); + + walking_process(); +} + +inline void walking_set_period(uint16_t period_us) +{ + walking_period=((float)period_us)/1000.0; +} + +inline uint16_t walking_get_period(void) +{ + return (uint16_t)(walking_period*1000); +} + +void walking_start(void) +{ + ram_data[BIOLOID_WALK_CNTRL]|=WALK_STATUS; + m_Ctrl_Running=0x01; +} + +void walking_stop(void) +{ + m_Ctrl_Running=0x00; +} + +uint8_t is_walking(void) +{ + if(ram_data[BIOLOID_WALK_CNTRL]&WALK_STATUS) + return 0x01; + else + return 0x00; +} + +// motion manager interface functions +void walking_process(void) +{ + float x_swap,y_swap,z_swap,a_swap,b_swap,c_swap; + float x_move_r,y_move_r,z_move_r,a_move_r,b_move_r,c_move_r; + float x_move_l,y_move_l,z_move_l,a_move_l,b_move_l,c_move_l; + float pelvis_offset_r,pelvis_offset_l; +// float m_Body_Swing_Y,m_Body_Swing_Z; + float angle[14],ep[12]; + + if(m_Time==0) + { + update_param_time(); + ram_data[BIOLOID_WALK_CNTRL]&=(~WALK_PHASE); + ram_data[BIOLOID_WALK_CNTRL]|=PHASE0; + if(m_Ctrl_Running==0x00) + { + if(m_X_Move_Amplitude==0 && m_Y_Move_Amplitude==0 && m_A_Move_Amplitude==0) + ram_data[BIOLOID_WALK_CNTRL]&=(~WALK_STATUS); + else + { + X_MOVE_AMPLITUDE=0.0; + Y_MOVE_AMPLITUDE=0.0; + A_MOVE_AMPLITUDE=0.0; + } + } + } + else if(m_Time>=(m_Phase_Time1-walking_period/2.0) && m_Time<(m_Phase_Time1+walking_period/2.0)) + { + update_param_move(); + ram_data[BIOLOID_WALK_CNTRL]&=(~WALK_PHASE); + ram_data[BIOLOID_WALK_CNTRL]|=PHASE1; + } + else if(m_Time>=(m_Phase_Time2-walking_period/2.0) && m_Time<(m_Phase_Time2+walking_period/2.0)) + { + update_param_time(); + m_Time=m_Phase_Time2; + ram_data[BIOLOID_WALK_CNTRL]&=(~WALK_PHASE); + ram_data[BIOLOID_WALK_CNTRL]|=PHASE2; + if(m_Ctrl_Running==0x00) + { + if(m_X_Move_Amplitude==0 && m_Y_Move_Amplitude==0 && m_A_Move_Amplitude==0) + ram_data[BIOLOID_WALK_CNTRL]&=~WALK_STATUS; + else + { + X_MOVE_AMPLITUDE=0.0; + Y_MOVE_AMPLITUDE=0.0; + A_MOVE_AMPLITUDE=0.0; + } + } + } + else if(m_Time>=(m_Phase_Time3-walking_period/2.0) && m_Time<(m_Phase_Time3+walking_period/2.0)) + { + update_param_move(); + ram_data[BIOLOID_WALK_CNTRL]&=(~WALK_PHASE); + ram_data[BIOLOID_WALK_CNTRL]|=PHASE3; + } + update_param_balance(); + + // Compute endpoints + x_swap=wsin(m_Time,m_X_Swap_PeriodTime,m_X_Swap_Phase_Shift,m_X_Swap_Amplitude,m_X_Swap_Amplitude_Shift); + y_swap=wsin(m_Time,m_Y_Swap_PeriodTime,m_Y_Swap_Phase_Shift,m_Y_Swap_Amplitude,m_Y_Swap_Amplitude_Shift); + z_swap=wsin(m_Time,m_Z_Swap_PeriodTime,m_Z_Swap_Phase_Shift,m_Z_Swap_Amplitude,m_Z_Swap_Amplitude_Shift); + a_swap=0; + b_swap=0; + c_swap=0; + if(m_Time<=m_SSP_Time_Start_L) + { + x_move_l=wsin(m_SSP_Time_Start_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift); + y_move_l=wsin(m_SSP_Time_Start_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift); + z_move_l=wsin(m_SSP_Time_Start_L,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_l=wsin(m_SSP_Time_Start_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,m_A_Move_Amplitude,m_A_Move_Amplitude_Shift); + x_move_r=wsin(m_SSP_Time_Start_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,-m_X_Move_Amplitude,-m_X_Move_Amplitude_Shift); + y_move_r=wsin(m_SSP_Time_Start_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift); + z_move_r=wsin(m_SSP_Time_Start_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_r=wsin(m_SSP_Time_Start_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift); + pelvis_offset_l=0; + pelvis_offset_r=0; + } + else if(m_Time<=m_SSP_Time_End_L) + { + x_move_l=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift); + y_move_l=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift); + z_move_l=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_l=wsin(m_Time,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,m_A_Move_Amplitude,m_A_Move_Amplitude_Shift); + x_move_r=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,-m_X_Move_Amplitude,-m_X_Move_Amplitude_Shift); + y_move_r=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift); + z_move_r=wsin(m_SSP_Time_Start_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_r=wsin(m_Time,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift); + pelvis_offset_l=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Pelvis_Swing/2.0,m_Pelvis_Swing/2.0); + pelvis_offset_r=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,-m_Pelvis_Offset/2.0,-m_Pelvis_Offset/2.0); + } + else if(m_Time<=m_SSP_Time_Start_R) + { + x_move_l=wsin(m_SSP_Time_End_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift); + y_move_l=wsin(m_SSP_Time_End_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift); + z_move_l=wsin(m_SSP_Time_End_L,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_l=wsin(m_SSP_Time_End_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,m_A_Move_Amplitude,m_A_Move_Amplitude_Shift); + x_move_r=wsin(m_SSP_Time_End_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,-m_X_Move_Amplitude,-m_X_Move_Amplitude_Shift); + y_move_r=wsin(m_SSP_Time_End_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift); + z_move_r=wsin(m_SSP_Time_Start_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_r=wsin(m_SSP_Time_End_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift); + pelvis_offset_l=0.0; + pelvis_offset_r=0.0; + } + else if(m_Time<=m_SSP_Time_End_R) + { + x_move_l=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift); + y_move_l=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift); + z_move_l=wsin(m_SSP_Time_End_L,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_l=wsin(m_Time,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_A_Move_Amplitude,m_A_Move_Amplitude_Shift); + x_move_r=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_X_Move_Amplitude,-m_X_Move_Amplitude_Shift); + y_move_r=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift); + z_move_r=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_r=wsin(m_Time,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift); + pelvis_offset_l=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Pelvis_Offset/2,m_Pelvis_Offset/2); + pelvis_offset_r=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,-m_Pelvis_Swing/2,-m_Pelvis_Swing/2); + } + else + { + x_move_l=wsin(m_SSP_Time_End_R,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift); + y_move_l=wsin(m_SSP_Time_End_R,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift); + z_move_l=wsin(m_SSP_Time_End_L,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_l=wsin(m_SSP_Time_End_R,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_A_Move_Amplitude,m_A_Move_Amplitude_Shift); + x_move_r=wsin(m_SSP_Time_End_R,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_X_Move_Amplitude,-m_X_Move_Amplitude_Shift); + y_move_r=wsin(m_SSP_Time_End_R,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift); + z_move_r=wsin(m_SSP_Time_End_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift); + c_move_r=wsin(m_SSP_Time_End_R,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift); + pelvis_offset_l=0.0; + pelvis_offset_r=0.0; + } + a_move_l=0.0; + b_move_l=0.0; + a_move_r=0.0; + b_move_r=0.0; + + ep[0]=x_swap+x_move_r+m_X_Offset; + ep[1]=y_swap+y_move_r-m_Y_Offset / 2.0; + ep[2]=z_swap+z_move_r+m_Z_Offset; + ep[3]=a_swap+a_move_r-m_R_Offset / 2.0; + ep[4]=b_swap+b_move_r+m_P_Offset; + ep[5]=c_swap+c_move_r-m_A_Offset / 2.0; + ep[6]=x_swap+x_move_l+m_X_Offset; + ep[7]=y_swap+y_move_l+m_Y_Offset / 2.0; + ep[8]=z_swap+z_move_l+m_Z_Offset; + ep[9]=a_swap+a_move_l+m_R_Offset / 2.0; + ep[10]=b_swap+b_move_l+m_P_Offset; + ep[11]=c_swap+c_move_l+m_A_Offset / 2.0; + + // Compute body swing +/* if(m_Time<=m_SSP_Time_End_L) + { + m_Body_Swing_Y=-ep[7]; + m_Body_Swing_Z=ep[8]; + } + else + { + m_Body_Swing_Y=-ep[1]; + m_Body_Swing_Z=ep[2]; + } + m_Body_Swing_Z-=BIOLOID_LEG_LENGTH;*/ + + // Compute arm swing + if(m_X_Move_Amplitude==0) + { + angle[12]=0; // Right + angle[13]=0; // Left + } + else + { + angle[12]=wsin(m_Time,m_PeriodTime,PI*1.5,-m_X_Move_Amplitude*m_Arm_Swing_Gain,0); + angle[13]=wsin(m_Time,m_PeriodTime,PI*1.5,m_X_Move_Amplitude*m_Arm_Swing_Gain,0); + } + + if(ram_data[BIOLOID_WALK_CNTRL]&WALK_STATUS) + { + m_Time += walking_period; + if(m_Time >= m_PeriodTime) + m_Time = 0; + } + + // Compute angles with the inverse kinematics + if((bioloid_leg_ik(&angle[0],ep[0],ep[1],ep[2],ep[3],ep[4],ep[5])!=1) || + (bioloid_leg_ik(&angle[6],ep[6],ep[7],ep[8],ep[9],ep[10],ep[11])!=1)) + return;// Do not use angles + + // Compute motor value + if(manager_get_module(R_HIP_YAW)==MM_WALKING) + manager_current_angles[R_HIP_YAW]=((180.0*(angle[0]-PI/4.0))/PI)*65536.0; + if(manager_get_module(R_HIP_ROLL)==MM_WALKING) + manager_current_angles[R_HIP_ROLL]=((-180.0*(angle[1]+pelvis_offset_r))/PI)*65536.0; + if(manager_get_module(R_HIP_PITCH)==MM_WALKING) + manager_current_angles[R_HIP_PITCH]=((180.0*angle[2])/PI-m_Hip_Pitch_Offset)*65536.0; + if(manager_get_module(R_KNEE)==MM_WALKING) + manager_current_angles[R_KNEE]=((-180.0*angle[3])/PI)*65536.0; + if(manager_get_module(R_ANKLE_PITCH)==MM_WALKING) + manager_current_angles[R_ANKLE_PITCH]=((-180.0*angle[4])/PI)*65536.0; + if(manager_get_module(R_ANKLE_ROLL)==MM_WALKING) + manager_current_angles[R_ANKLE_ROLL]=((180.0*angle[5])/PI)*65536.0; + if(manager_get_module(L_HIP_YAW)==MM_WALKING) + manager_current_angles[L_HIP_YAW]=((180.0*(angle[6]+PI/4.0))/PI)*65536.0; + if(manager_get_module(L_HIP_ROLL)==MM_WALKING) + manager_current_angles[L_HIP_ROLL]=((-180.0*(angle[7]+pelvis_offset_l))/PI)*65536.0; + if(manager_get_module(L_HIP_PITCH)==MM_WALKING) + manager_current_angles[L_HIP_PITCH]=((-180.0*angle[8])/PI-m_Hip_Pitch_Offset)*65536.0; + if(manager_get_module(L_KNEE)==MM_WALKING) + manager_current_angles[L_KNEE]=((180.0*angle[9])/PI)*65536.0; + if(manager_get_module(L_ANKLE_PITCH)==MM_WALKING) + manager_current_angles[L_ANKLE_PITCH]=((180.0*angle[10])/PI)*65536.0; + if(manager_get_module(L_ANKLE_ROLL)==MM_WALKING) + manager_current_angles[L_ANKLE_ROLL]=((180.0*angle[11])/PI)*65536.0; + if(manager_get_module(R_SHOULDER_PITCH)==MM_WALKING) + manager_current_angles[R_SHOULDER_PITCH]=((180.0*angle[12])/PI)*65536.0; + if(manager_get_module(L_SHOULDER_PITCH)==MM_WALKING) + manager_current_angles[L_SHOULDER_PITCH]=((-180.0*angle[13])/PI)*65536.0; +} + +// operation functions +uint8_t walking_in_range(unsigned short int address, unsigned short int length) +{ + if(ram_in_window(WALK_BASE_ADDRESS,WALK_MEM_LENGTH,address,length) || + ram_in_window(WALK_EEPROM_ADDRESS,WALK_EEPROM_LENGTH,address,length)) + return 0x01; + else + return 0x00; +} + +void walking_process_read_cmd(unsigned short int address,unsigned short int length,unsigned char *data) +{ + +} + +void walking_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data) +{ + uint16_t i; + + // walk control + if(ram_in_range(BIOLOID_WALK_CNTRL,address,length)) + { + if(data[BIOLOID_WALK_CNTRL-address]&WALK_START) + walking_start(); + if(data[BIOLOID_WALK_CNTRL-address]&WALK_STOP) + walking_stop(); + } + // walk parameters + for(i=WALK_EEPROM_ADDRESS;i<=WALK_EEPROM_ADDRESS+WALK_EEPROM_LENGTH;i++) + if(ram_in_range(i,address,length)) + ram_data[i]=data[i-address]; +} +