#include "Arduino.h" #include "Hippie.h" #include void Hippie::init(int YL, int YR, int RL, int RR) { servo_pins[0] = YL; servo_pins[1] = YR; servo_pins[2] = RL; servo_pins[3] = RR; attachServos(); isHippieResting=false; for (int i = 0; i < 4; i++) servo_position[i] = 90; } void Hippie::init_with_trim(int YL, int YR, int RL, int RR, int OYL, int OYR, int ORL, int ORR) { servo_pins[0] = YL; servo_pins[1] = YR; servo_pins[2] = RL; servo_pins[3] = RR; servo[0].SetTrim(OYL); servo[1].SetTrim(OYR); servo[2].SetTrim(ORL); servo[3].SetTrim(ORR); attachServos(); isHippieResting=false; for (int i = 0; i < 4; i++) servo_position[i] = 90; } /////////////////////////////////////////////////////////////////// //-- ATTACH & DETACH FUNCTIONS ----------------------------------// /////////////////////////////////////////////////////////////////// void Hippie::attachServos(){ servo[0].attach(servo_pins[0]); servo[1].attach(servo_pins[1]); servo[2].attach(servo_pins[2]); servo[3].attach(servo_pins[3]); } void Hippie::detachServos(){ servo[0].detach(); servo[1].detach(); servo[2].detach(); servo[3].detach(); } /////////////////////////////////////////////////////////////////// //-- BASIC MOTION FUNCTIONS -------------------------------------// /////////////////////////////////////////////////////////////////// void Hippie::_moveServos(int time, int servo_target[]) { attachServos(); if(getRestState()==true){ setRestState(false); } if(time>10){ for (int i = 0; i < 4; i++) increment[i] = ((servo_target[i]) - servo_position[i]) / (time / 10.0); final_time = millis() + time; for (int iteration = 1; millis() < final_time; iteration++) { partial_time = millis() + 10; for (int i = 0; i < 4; i++) servo[i].SetPosition(servo_position[i] + (iteration * increment[i])); while (millis() < partial_time); //pause } } else{ for (int i = 0; i < 4; i++) servo[i].SetPosition(servo_target[i]); } for (int i = 0; i < 4; i++) servo_position[i] = servo_target[i]; } void Hippie::oscillateServos(int A[4], int O[4], int T, double phase_diff[4], float cycle=1){ for (int i=0; i<4; i++) { servo[i].SetO(O[i]); servo[i].SetA(A[i]); servo[i].SetT(T); servo[i].SetPh(phase_diff[i]); servo[i].SetTrim(servo_trim[i]); } double ref=millis(); for (double x=ref; x<=T*cycle+ref; x=millis()){ for (int i=0; i<4; i++){ servo[i].refresh(); } } } void Hippie::_execute(int A[4], int O[4], int T, double phase_diff[4], float steps = 1.0){ attachServos(); if(getRestState()==true){ setRestState(false); } int cycles=(int)steps; //-- Execute complete cycles if (cycles >= 1) for(int i = 0; i < cycles; i++) oscillateServos(A,O, T, phase_diff); //-- Execute the final not complete cycle oscillateServos(A,O, T, phase_diff,(float)steps-cycles); } /////////////////////////////////////////////////////////////////// //-- HOME = Hippie at rest position -------------------------------// /////////////////////////////////////////////////////////////////// void Hippie::home(){ if(isHippieResting==false){ //Go to rest position only if necessary int homes[4]={90, 90, 90, 90}; //All the servos at rest position _moveServos(500,homes); //Move the servos in half a second detachServos(); isHippieResting=true; } } bool Hippie::getRestState(){ return isHippieResting; } void Hippie::setRestState(bool state){ isHippieResting = state; } /////////////////////////////////////////////////////////////////// //-- PREDETERMINED MOTION SEQUENCES -----------------------------// /////////////////////////////////////////////////////////////////// //--------------------------------------------------------- //-- Hippie movement: Jump //-- Parameters: //-- steps: Number of steps //-- T: Period //--------------------------------------------------------- void Hippie::jump(float steps, int T){ int up[]={90,90,165,15}; _moveServos(T,up); int down[]={90,90,90,90}; _moveServos(T,down); } //--------------------------------------------------------- //-- Hippie Test Positions (bring feets and hips in certain position) //--------------------------------------------------------- void Hippie::test_pos(){ int left_feet_up[4]={90,0,90,30}; //watch from view of robot: [3] = left leg ... by + value: turn right _moveServos(1000,left_feet_up); // [4] = right leg ... by + value: right side up } //--------------------------------------------------------- //-- Hippie gait: Walking (forward or backward) //-- Parameters: //-- * steps: Number of steps //-- * T : Period //-- * Dir: Direction: FORWARD / BACKWARD //--------------------------------------------------------- void Hippie::walk(float steps, int T, int dir){ //-- Oscillator parameters for walking //-- Hip sevos are in phase //-- Feet servos are in phase //-- Hip and feet are 90 degrees out of phase //-- -90 : Walk forward //-- 90 : Walk backward //-- Feet servos also have the same offset (for tiptoe a little bit) int A[4]= {30, 30, 40, 40}; //20 int O[4] = {0, 0, 4, 30}; //-4 double phase_diff[4] = {0, 0, DEG2RAD(dir * -90), DEG2RAD(dir * -90)}; if ( dir == -1) { double phase_diff[4] = {0, 0, DEG2RAD(dir * 90), DEG2RAD(dir * 90)}; } //-- Let's oscillate the servos! _execute(A, O, T, phase_diff, steps); } //--------------------------------------------------------- //-- Hippie gait: Turning (left or right) //-- Parameters: //-- * Steps: Number of steps //-- * T: Period //-- * Dir: Direction: LEFT / RIGHT //--------------------------------------------------------- void Hippie::turn(float steps, int T, int dir){ //-- Same coordination than for walking (see Hippie::walk) //-- The Amplitudes of the hip's oscillators are not igual //-- When the right hip servo amplitude is higher, the steps taken by //-- the right leg are bigger than the left. So, the robot describes an //-- left arc int A[4]= {30, 30, 20, 20}; int O[4] = {0, 0, 4, 30}; double phase_diff[4] = {0, 0, DEG2RAD(-90), DEG2RAD(-90)}; if (dir == LEFT) { A[0] = 50; //-- Left hip servo A[1] = 10; //-- Right hip servo } else { A[0] = 10; A[1] = 50; A[2] = 40; } //-- Let's oscillate the servos! _execute(A, O, T, phase_diff, steps); } //--------------------------------------------------------- //-- Hippie gait: Lateral bend //-- Parameters: //-- steps: Number of bends //-- T: Period of one bend //-- dir: RIGHT=Right bend LEFT=Left bend //--------------------------------------------------------- void Hippie::bend (int steps, int T, int dir){ //Parameters of all the movements. Default: Left bend int bend1[4]={90, 90, 62, 35}; int bend2[4]={90, 90, 62, 105+60}; int homes[4]={90, 90, 90, 90}; //Time of one bend, constrained in order to avoid movements too fast. //T=max(T, 600); //Changes in the parameters if right direction is chosen if(dir==-1) { bend1[2]=180-35; bend1[3]=180-60; //Not 65. Hippie is unbalanced bend2[2]=180-105; bend2[3]=180-60; } //Time of the bend movement. Fixed parameter to avoid falls int T2=800; //Bend movement for (int i=0;i