160 likes | 273 Views
Anthony Calce Gordon Klein Vince Wu Kyle Watters. Team Helitronics. Overview. Background Difficulties Risk Management Modifications to Specs Algorithms Flight, CCPM Swashplate, Servo, Interrupt Code Sensor Interrupt Code Safety Tether Progress to Date Current Budget
E N D
Anthony Calce Gordon Klein Vince Wu Kyle Watters Team Helitronics
Overview • Background • Difficulties • Risk Management • Modifications to Specs • Algorithms • Flight, CCPM Swashplate, Servo, Interrupt Code • Sensor Interrupt Code • Safety Tether • Progress to Date • Current Budget • Current Test Setup
Background • Flight Constraints • Fast reaction time • Onboard vision processing • Dedicated real-time flight controller
Difficulties • Servo Control • Trouble controlling servos with PWM • OpenCV vision platform cannot be used with BeagleBoard • OpenCV is not optimized for the OMAP3 • Too many floating point operations • Need to write vision algorithms from scratch using fixed point arithmetic
Risk Management • Limited budget does not allow for divergence in the budget • A new safety tether has been designed • Team is seeking more sponsorship • Limited precision of sensors can make flight algorithms unstable • Expensive in-kind sensors may be available • Time is getting limited
Modifications to Specs • Sensor Data / Flight Control • Sensory information and servos are controlled via interrupt driven code, as opposed to original polling technique • Safety Considerations • The previous proposed tethering system has been changed to a more sturdy design for safe testing • Hardware • Helicopter change from Shenzen KDS450SV to E-flite Blade 400 • Future considerations • If budget permits, design a PCB for a cleaner hardware layout
Algorithms - Flight • Three servos control the swashplate • Swashplate position changes as throttle increases • Graphs have been generated to show this relationship
CCPM Swashplate • Plate motion up and down changes pitch • Rotating about the same location changes thrust vector direction
Servo Calculation • Take three points (120° apart) on a circle and calculate their new location based off of rotations
Flight Code Interrupt Vector Function ISR (TIMER2_OVF_vect){ ++ISRCount; // increment the overlflow counter if (ISRCount == servos[Channel].counter ) { // are we on the final iteration for this channel TCNT2 = servos[Channel].remainder; // yes, set count for overflow after remainder ticks } else if(ISRCount > servos[Channel].counter){ // we have finished timing the channel so pulse it low and move on if(servos[Channel].Pin.isActive == true) // check if activated digitalWrite( servos[Channel].Pin.nbr,LOW); // pulse this channel low if active Channel++; // increment to the next channel ISRCount = 0; // reset the isr iteration counter TCNT2 = 0; // reset the clock counter register if( (Channel != FRAME_SYNC_INDEX) && (Channel <= NBR_CHANNELS) ){ // check if we need to pulse this channel if(servos[Channel].Pin.isActive == true) // check if activated digitalWrite( servos[Channel].Pin.nbr,HIGH); // its an active channel so pulse it high } else if(Channel > NBR_CHANNELS){ Channel = 0; // all done so start over } } } Write Out to Servo Function static void writeChan(uint8_t chan, int pulsewidth) { if( (chan > 0) && (chan <= NBR_CHANNELS) ) // ensure channel is valid { if( pulsewidth < MIN_PULSE_WIDTH ) // ensure pulse width is valid pulsewidth = MIN_PULSE_WIDTH; else if( pulsewidth > MAX_PULSE_WIDTH ) pulsewidth = MAX_PULSE_WIDTH; pulsewidth -=DELAY_ADJUST; // subtract the time it takes to process the start and end pulses (mostly from digitalWrite) servos[chan].counter = pulsewidth / 128; servos[chan].remainder = 255 - (2 * (pulsewidth - ( servos[chan].counter * 128))); // the number of 0.5us ticks for timer overflow }}
Sensor Code Interrupt Vector Function ISR(ADC_vect){ switch(channel){ case 0b00000001: totalZ += ((ADCL) | ((ADCH)<<8)); set(ADMUX, MUX0); channel<<=1; break; … case 0b00000100: totalY += ((ADCL) | ((ADCH)<<8)); set(ADMUX, MUX0); channel<<=1; break; case 0b00001000: totalGyroY += ((ADCL) | ((ADCH)<<8)); clr(ADMUX, MUX0); clr(ADMUX, MUX1); set(ADMUX, MUX2); channel<<=1; break; case 0b00010000: totalGyroX += ((ADCL) | ((ADCH)<<8)); set(ADMUX, MUX0); channel<<=1; break; case 0b00100000: totalGyroZ += ((ADCL) | ((ADCH)<<8)); clr(ADMUX, MUX0); clr(ADMUX, MUX2); count++; channel ^= 0b00100001; //reset sequence //channel<<=1; break; … default: channel = 0b00000001; // bad state restart break; } • Original polling technique lead to delay in new measurements • Interrupt driven code guarantees us fresh data at a predefined frequency
Safety Tether Old tether consisted of four ropes Blade will hit the tether if rope is not taught Tedious to setup New design consists of a 35° swivelball joint Allows for safer testing of stability code
Current Test Setup Arduino and IMU Sensor BeagleBoard
A fully autonomous helicopter capable of advanced image processing and navigation. Deliverable