https://hades.mech.northwestern.edu//api.php?action=feedcontributions&user=Anthony+Franco&feedformat=atomMech - User contributions [en]2024-03-28T14:36:53ZUser contributionsMediaWiki 1.35.9https://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12992PIC Servo Controller2009-03-20T16:24:24Z<p>Anthony Franco: /* Code */</p>
<hr />
<div>==Theory==<br />
<br />
This PIC code and circuit will give you position control over any coupled motor/potentiometer pair. This was tested using a hacked hobby servo but theoretically would give you the same kind of control using any size motor as long as the output shaft was mechanically coupled to the rotation of the feedback pot.<br />
<br />
The code and theory borrows from these other pages:<br />
*[[Analog Input]]<br />
*[[Pulse width modulation]]<br />
*[[Running RC servos]]<br />
*[[Servo skeleton with fast & slow interrupts]]<br />
<br />
==Code==<br />
<pre><br />
#include <18f4520.h> <br />
#device ADC=10 // set ADC to 10 bit accuracy<br />
#fuses HS,NOLVP,NOWDT,NOPROTECT<br />
#use delay(clock=40000000)<br />
#use rs232(baud=19200, UART1) // hardware uart much better; uses RC6/TX and RC7/RX <br />
<br />
#define PanTorqueMax 650 // 650 corresponds to 100% duty cycle for driving the motor full on in one dirction<br />
#define PanTorqueMin -650 // -650 corresponds to 0% duty cylce for driving the motor full on in the other direction<br />
#define pGain 0 // This is the Proportional coefficient, adjust this first<br />
#define iGain 0 // This is the Integral coefficient, adjust this second<br />
#define dGain 0 // This is the Derivative coefficient, adjust this last<br />
<br />
signed int32 rise,fall,pulse_width;<br />
int32 msecs=0;<br />
signed int32 PanTarget = 0;<br />
signed int32 PanActual = 0;<br />
signed int32 PanError, PanErrorLastTime=0, PanIntegral, PanDerivative, PanTorque=0;<br />
int16 value;<br />
int i=0;<br />
<br />
#int_ccp1 // This is the CCP capture interrupt, this allows you to use one pin (CCP1) to capture both<br />
// the rising edge and falling edge of the servo PWM signal, which leaves the other CCP pin<br />
// open for drving the servo motor<br />
void isr()<br />
{<br />
if (i==0) {output_high(PIN_A1);<br />
rise = CCP_1;<br />
setup_ccp1(CCP_CAPTURE_FE);<br />
i=1;}<br />
else if (i==1) {output_low(PIN_A1);<br />
fall = CCP_1;<br />
pulse_width = fall - rise;<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
i=0;}<br />
}<br />
<br />
<br />
#INT_TIMER2 // designates that this is the routine to call when timer2 overflows<br />
void Timer2isr() {<br />
msecs++; // keep track of time<br />
<br />
if ((msecs & 7) == 0) { // servo routine every 8ms is plenty. 125x/sec<br />
output_high(PIN_B0);<br />
PanTarget=pulse_width;<br />
PanActual=read_adc();<br />
PanActual=25*PanActual; // 25 is the coefficient needed to scale up the adc reading to correspond to<br />
// standard servo pulse widths (.5 to 2.5 ms)<br />
<br />
PanError = PanTarget - PanActual; // position error<br />
PanIntegral += PanError;<br />
PanDerivative = PanError - PanErrorLastTime;<br />
PanErrorLastTime = PanError;<br />
<br />
PanTorque = pGain * PanError + iGain * PanIntegral + dGain * PanDerivative; <br />
TorqueShifted=PanTorque>>16;<br />
if (PanTorque < PanTorqueMin) PanTorque = PanTorqueMin;<br />
if (PanTorque > PanTorqueMax) PanTorque = PanTorqueMax;<br />
<br />
if (PanActual<PanTarget){<br />
output_low(PIN_C0);<br />
set_pwm2_duty(PanTorque); <br />
}<br />
else if (PanActual>PanTarget){<br />
output_high(PIN_C0);<br />
set_pwm2_duty(650 + PanTorque);<br />
}<br />
<br />
output_low(PIN_B0);<br />
}<br />
}<br />
<br />
<br />
<br />
void main() {<br />
<br />
setup_timer_2(T2_DIV_BY_4, 156, 16); // clock at 16KHz, interrupt every 4*25nS * 4 * 156 * 16 = 1.0mS<br />
setup_timer_1(T1_INTERNAL); //start timer 1<br />
<br />
setup_adc_ports(AN0); // Enable analog inputs; This will read the ADC on pin AN0<br />
setup_adc(ADC_CLOCK_INTERNAL); <br />
<br />
setup_ccp2(CCP_PWM); // PWM output on CCP1/RC2, pin 17<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
<br />
enable_interrupts(INT_CCP1); <br />
enable_interrupts(INT_TIMER2);<br />
enable_interrupts(GLOBAL);<br />
<br />
//set_pwm2_duty(value); // h-bridge for pan motor from CCP2 (pin 16, RC1) to C0 (pin 16)<br />
//output_high(PIN_C3);<br />
<br />
<br />
while (TRUE) { <br />
<br />
//This is useful for debugging using the RS-232 serial communication<br />
<br />
printf("pulse width: %Lu Target: %Ld Actual: %Ld Torque: %Ld \r\n", pulse_width,PanTarget,PanActual,PanTorque);<br />
<br />
<br />
<br />
}<br />
}<br />
<br />
</pre><br />
<br />
==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|center]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12868Vision-based Cannon2009-03-20T06:32:51Z<p>Anthony Franco: /* Electronics */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Tony Franco and Scott Mueller|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
*This is the main servo PWM generation and controller circuit with the Master and two Slaves<br />
<br />
<br clear=all><br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
*This is the Nerf rocket Fire Control circuit<br />
<br />
<br clear=all><br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
*These are all four PICs used for controlling the project. One Master, two Slaves, and the Fire Control<br />
<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Image:Master PWM Generator.png|PWM Generator|thumb|400px|right]]<br />
<br />
*[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
<br clear=all><br />
<br />
<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Control Circuit|thumb|600px|right]]<br />
<br />
*[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
*[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
*[[RC Servo Theory]]<br />
<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:Master_PWM_Generator.png&diff=12867File:Master PWM Generator.png2009-03-20T06:29:55Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12866PIC Servo Controller2009-03-20T06:28:53Z<p>Anthony Franco: /* Theory */</p>
<hr />
<div>==Theory==<br />
<br />
This PIC code and circuit will give you position control over any coupled motor/potentiometer pair. This was tested using a hacked hobby servo but theoretically would give you the same kind of control using any size motor as long as the output shaft was mechanically coupled to the rotation of the feedback pot.<br />
<br />
The code and theory borrows from these other pages:<br />
*[[Analog Input]]<br />
*[[Pulse width modulation]]<br />
*[[Running RC servos]]<br />
*[[Servo skeleton with fast & slow interrupts]]<br />
<br />
==Code==<br />
<pre><br />
#include <18f4520.h> <br />
#device ADC=10 // set ADC to 10 bit accuracy<br />
#fuses HS,NOLVP,NOWDT,NOPROTECT<br />
#use delay(clock=40000000)<br />
#use rs232(baud=19200, UART1) // hardware uart much better; uses RC6/TX and RC7/RX <br />
<br />
#define PanTorqueMax 650 // 650 corresponds to 100% duty cycle for driving the motor full on in one dirction<br />
#define PanTorqueMin -650 // -650 corresponds to 0% duty cylce for driving the motor full on in the other direction<br />
#define pGain 0 // This is the Proportional coefficient, adjust this first<br />
#define iGain 0 // This is the Integral coefficient, adjust this second<br />
#define dGain 0 // This is the Derivative coefficient, adjust this last<br />
<br />
signed int32 rise,fall,pulse_width;<br />
int32 msecs=0;<br />
signed int32 PanTarget = 0;<br />
signed int32 PanActual = 0;<br />
signed int32 PanError, PanErrorLastTime=0, PanIntegral, PanDerivative, PanTorque=0;<br />
int16 value;<br />
int i=0;<br />
<br />
#int_ccp1 // This is the CCP capture interrupt, this allows you to use one pin (CCP1) to capture both<br />
// the rising edge and falling edge of the servo PWM signal, which leaves the other CCP pin<br />
// open for drving the servo motor<br />
void isr()<br />
{<br />
if (i==0) {output_high(PIN_A1);<br />
rise = CCP_1;<br />
setup_ccp1(CCP_CAPTURE_FE);<br />
i=1;}<br />
else if (i==1) {output_low(PIN_A1);<br />
fall = CCP_1;<br />
pulse_width = fall - rise;<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
i=0;}<br />
}<br />
<br />
<br />
#INT_TIMER2 // designates that this is the routine to call when timer2 overflows<br />
void Timer2isr() {<br />
msecs++; // keep track of time<br />
<br />
if ((msecs & 7) == 0) { // servo routine every 8ms is plenty. 125x/sec<br />
output_high(PIN_B0);<br />
PanTarget=pulse_width;<br />
PanActual=read_adc();<br />
PanActual=25*PanActual;<br />
<br />
PanError = PanTarget - PanActual; // position error<br />
PanIntegral += PanError;<br />
PanDerivative = PanError - PanErrorLastTime;<br />
PanErrorLastTime = PanError;<br />
<br />
PanTorque = pGain * PanError + iGain * PanIntegral + dGain * PanDerivative; <br />
TorqueShifted=PanTorque>>16;<br />
if (PanTorque < PanTorqueMin) PanTorque = PanTorqueMin;<br />
if (PanTorque > PanTorqueMax) PanTorque = PanTorqueMax;<br />
<br />
if (PanActual<PanTarget){<br />
output_low(PIN_C0);<br />
set_pwm2_duty(PanTorque); <br />
}<br />
else if (PanActual>PanTarget){<br />
output_high(PIN_C0);<br />
set_pwm2_duty(650 + PanTorque);<br />
}<br />
<br />
output_low(PIN_B0);<br />
}<br />
}<br />
<br />
<br />
<br />
void main() {<br />
<br />
setup_timer_2(T2_DIV_BY_4, 156, 16); // clock at 16KHz, interrupt every 4*25nS * 4 * 156 * 16 = 1.0mS<br />
setup_timer_1(T1_INTERNAL); //start timer 1<br />
<br />
setup_adc_ports(AN0); // Enable analog inputs; This will read the ADC on pin AN0<br />
setup_adc(ADC_CLOCK_INTERNAL); <br />
<br />
setup_ccp2(CCP_PWM); // PWM output on CCP1/RC2, pin 17<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
<br />
enable_interrupts(INT_CCP1); <br />
enable_interrupts(INT_TIMER2);<br />
enable_interrupts(GLOBAL);<br />
<br />
//set_pwm2_duty(value); // h-bridge for pan motor from CCP2 (pin 16, RC1) to C0 (pin 16)<br />
//output_high(PIN_C3);<br />
<br />
<br />
while (TRUE) { <br />
<br />
//This is useful for debugging using the RS-232 serial communication<br />
<br />
printf("pulse width: %Lu Target: %Ld Actual: %Ld Torque: %Ld \r\n", pulse_width,PanTarget,PanActual,PanTorque);<br />
<br />
<br />
<br />
}<br />
}<br />
<br />
</pre><br />
<br />
==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|center]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12865PIC Servo Controller2009-03-20T06:24:36Z<p>Anthony Franco: /* Code */</p>
<hr />
<div>==Theory==<br />
<br />
This PIC code and circuit will give you position control over any coupled motor/potentiometer pair. This was tested using a hacked hobby servo but theoretically would give you the same kind of control using any size motor as long as the output shaft was mechanically coupled to the rotation of the feedback pot.<br />
<br />
<br />
==Code==<br />
<pre><br />
#include <18f4520.h> <br />
#device ADC=10 // set ADC to 10 bit accuracy<br />
#fuses HS,NOLVP,NOWDT,NOPROTECT<br />
#use delay(clock=40000000)<br />
#use rs232(baud=19200, UART1) // hardware uart much better; uses RC6/TX and RC7/RX <br />
<br />
#define PanTorqueMax 650 // 650 corresponds to 100% duty cycle for driving the motor full on in one dirction<br />
#define PanTorqueMin -650 // -650 corresponds to 0% duty cylce for driving the motor full on in the other direction<br />
#define pGain 0 // This is the Proportional coefficient, adjust this first<br />
#define iGain 0 // This is the Integral coefficient, adjust this second<br />
#define dGain 0 // This is the Derivative coefficient, adjust this last<br />
<br />
signed int32 rise,fall,pulse_width;<br />
int32 msecs=0;<br />
signed int32 PanTarget = 0;<br />
signed int32 PanActual = 0;<br />
signed int32 PanError, PanErrorLastTime=0, PanIntegral, PanDerivative, PanTorque=0;<br />
int16 value;<br />
int i=0;<br />
<br />
#int_ccp1 // This is the CCP capture interrupt, this allows you to use one pin (CCP1) to capture both<br />
// the rising edge and falling edge of the servo PWM signal, which leaves the other CCP pin<br />
// open for drving the servo motor<br />
void isr()<br />
{<br />
if (i==0) {output_high(PIN_A1);<br />
rise = CCP_1;<br />
setup_ccp1(CCP_CAPTURE_FE);<br />
i=1;}<br />
else if (i==1) {output_low(PIN_A1);<br />
fall = CCP_1;<br />
pulse_width = fall - rise;<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
i=0;}<br />
}<br />
<br />
<br />
#INT_TIMER2 // designates that this is the routine to call when timer2 overflows<br />
void Timer2isr() {<br />
msecs++; // keep track of time<br />
<br />
if ((msecs & 7) == 0) { // servo routine every 8ms is plenty. 125x/sec<br />
output_high(PIN_B0);<br />
PanTarget=pulse_width;<br />
PanActual=read_adc();<br />
PanActual=25*PanActual;<br />
<br />
PanError = PanTarget - PanActual; // position error<br />
PanIntegral += PanError;<br />
PanDerivative = PanError - PanErrorLastTime;<br />
PanErrorLastTime = PanError;<br />
<br />
PanTorque = pGain * PanError + iGain * PanIntegral + dGain * PanDerivative; <br />
TorqueShifted=PanTorque>>16;<br />
if (PanTorque < PanTorqueMin) PanTorque = PanTorqueMin;<br />
if (PanTorque > PanTorqueMax) PanTorque = PanTorqueMax;<br />
<br />
if (PanActual<PanTarget){<br />
output_low(PIN_C0);<br />
set_pwm2_duty(PanTorque); <br />
}<br />
else if (PanActual>PanTarget){<br />
output_high(PIN_C0);<br />
set_pwm2_duty(650 + PanTorque);<br />
}<br />
<br />
output_low(PIN_B0);<br />
}<br />
}<br />
<br />
<br />
<br />
void main() {<br />
<br />
setup_timer_2(T2_DIV_BY_4, 156, 16); // clock at 16KHz, interrupt every 4*25nS * 4 * 156 * 16 = 1.0mS<br />
setup_timer_1(T1_INTERNAL); //start timer 1<br />
<br />
setup_adc_ports(AN0); // Enable analog inputs; This will read the ADC on pin AN0<br />
setup_adc(ADC_CLOCK_INTERNAL); <br />
<br />
setup_ccp2(CCP_PWM); // PWM output on CCP1/RC2, pin 17<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
<br />
enable_interrupts(INT_CCP1); <br />
enable_interrupts(INT_TIMER2);<br />
enable_interrupts(GLOBAL);<br />
<br />
//set_pwm2_duty(value); // h-bridge for pan motor from CCP2 (pin 16, RC1) to C0 (pin 16)<br />
//output_high(PIN_C3);<br />
<br />
<br />
while (TRUE) { <br />
<br />
//This is useful for debugging using the RS-232 serial communication<br />
<br />
printf("pulse width: %Lu Target: %Ld Actual: %Ld Torque: %Ld \r\n", pulse_width,PanTarget,PanActual,PanTorque);<br />
<br />
<br />
<br />
}<br />
}<br />
<br />
</pre><br />
<br />
==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|center]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12839Vision-based Cannon2009-03-20T06:05:24Z<p>Anthony Franco: /* Circuits */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Tony Franco and Scott Mueller|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
*This is the main servo PWM generation and controller circuit with the Master and two Slaves<br />
<br />
<br clear=all><br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
*This is the Nerf rocket Fire Control circuit<br />
<br />
<br clear=all><br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
*These are all four PICs used for controlling the project. One Master, two Slaves, and the Fire Control<br />
<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Control Circuit|thumb|600px|right]]<br />
<br />
*[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
*[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
*[[RC Servo Theory]]<br />
<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12825Vision-based Cannon2009-03-20T05:58:00Z<p>Anthony Franco: /* Team Members */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Tony Franco and Scott Mueller|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Control Circuit|thumb|600px|right]]<br />
<br />
*[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
*[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
*[[RC Servo Theory]]<br />
<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12821Vision-based Cannon2009-03-20T05:57:05Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Control Circuit|thumb|600px|right]]<br />
<br />
*[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
*[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
*[[RC Servo Theory]]<br />
<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12818Vision-based Cannon2009-03-20T05:56:11Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|right]]<br />
<br />
*[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
*[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
*[[RC Servo Theory]]<br />
<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12810Vision-based Cannon2009-03-20T05:50:05Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|right]]<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12805PIC Servo Controller2009-03-20T05:47:49Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>==Code==<br />
<pre><br />
#include <18f4520.h> <br />
#device ADC=10 // set ADC to 10 bit accuracy<br />
#fuses HS,NOLVP,NOWDT,NOPROTECT<br />
#use delay(clock=40000000)<br />
#use rs232(baud=19200, UART1) // hardware uart much better; uses RC6/TX and RC7/RX <br />
<br />
#define PanTorqueMax 650 // 650 corresponds to 100% duty cycle for driving the motor full on in one dirction<br />
#define PanTorqueMin -650 // -650 corresponds to 0% duty cylce for driving the motor full on in the other direction<br />
#define pGain 0 // This is the Proportional coefficient, adjust this first<br />
#define iGain 0 // This is the Integral coefficient, adjust this second<br />
#define dGain 0 // This is the Derivative coefficient, adjust this last<br />
<br />
signed int32 rise,fall,pulse_width;<br />
int32 msecs=0;<br />
signed int32 PanTarget = 0;<br />
signed int32 PanActual = 0;<br />
signed int32 PanError, PanErrorLastTime=0, PanIntegral, PanDerivative, PanTorque=0;<br />
int16 value;<br />
int i=0;<br />
<br />
#int_ccp1 // This is the CCP capture interrupt, this allows you to use one pin (CCP1) to capture both<br />
// the rising edge and falling edge of the servo PWM signal, which leaves the other CCP pin<br />
// open for drving the servo motor<br />
void isr()<br />
{<br />
if (i==0) {output_high(PIN_A1);<br />
rise = CCP_1;<br />
setup_ccp1(CCP_CAPTURE_FE);<br />
i=1;}<br />
else if (i==1) {output_low(PIN_A1);<br />
fall = CCP_1;<br />
pulse_width = fall - rise;<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
i=0;}<br />
}<br />
<br />
<br />
#INT_TIMER2 // designates that this is the routine to call when timer2 overflows<br />
void Timer2isr() {<br />
msecs++; // keep track of time<br />
<br />
if ((msecs & 7) == 0) { // servo routine every 8ms is plenty. 125x/sec<br />
output_high(PIN_B0);<br />
PanTarget=pulse_width;<br />
PanActual=read_adc();<br />
PanActual=25*PanActual;<br />
<br />
PanError = PanTarget - PanActual; // position error<br />
PanIntegral += PanError;<br />
PanDerivative = PanError - PanErrorLastTime;<br />
PanErrorLastTime = PanError;<br />
<br />
PanTorque = pGain * PanError + iGain * PanIntegral + dGain * PanDerivative; <br />
TorqueShifted=PanTorque>>16;<br />
if (PanTorque < PanTorqueMin) PanTorque = PanTorqueMin;<br />
if (PanTorque > PanTorqueMax) PanTorque = PanTorqueMax;<br />
<br />
if (PanActual<PanTarget){<br />
output_low(PIN_C0);<br />
set_pwm2_duty(PanTorque); <br />
}<br />
else if (PanActual>PanTarget){<br />
output_high(PIN_C0);<br />
set_pwm2_duty(650 + PanTorque);<br />
}<br />
<br />
output_low(PIN_B0);<br />
}<br />
}<br />
<br />
<br />
<br />
void main() {<br />
<br />
setup_timer_2(T2_DIV_BY_4, 156, 16); // clock at 16KHz, interrupt every 4*25nS * 4 * 156 * 16 = 1.0mS<br />
setup_timer_1(T1_INTERNAL); //start timer 1<br />
<br />
setup_adc_ports(AN0); // Enable analog inputs; This will read the ADC on pin AN0<br />
setup_adc(ADC_CLOCK_INTERNAL); <br />
<br />
setup_ccp2(CCP_PWM); // PWM output on CCP1/RC2, pin 17<br />
setup_ccp1(CCP_CAPTURE_RE);<br />
<br />
enable_interrupts(INT_CCP1); <br />
enable_interrupts(INT_TIMER2);<br />
enable_interrupts(GLOBAL);<br />
<br />
//set_pwm2_duty(value); // h-bridge for pan motor from CCP2 (pin 16, RC1) to C0 (pin 16)<br />
//output_high(PIN_C3);<br />
<br />
<br />
while (TRUE) { <br />
<br />
//This is useful for debugging using the RS-232 serial communication<br />
<br />
printf("pulse width: %Lu Target: %Ld Actual: %Ld Torque: %Ld \r\n", pulse_width,PanTarget,PanActual,PanTorque);<br />
<br />
<br />
<br />
}<br />
}<br />
<br />
</pre> <br />
<br />
<br />
<br />
<br />
<br />
==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|center]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12796PIC Servo Controller2009-03-20T05:44:02Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|600px|center]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12795PIC Servo Controller2009-03-20T05:43:37Z<p>Anthony Franco: /* Blah */</p>
<hr />
<div>==Circuit==<br />
<br />
[[Image:PIC Servo Controller.png|Servo Drive and Control Circuit|thumb|450px|right]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:PIC_Servo_Controller.png&diff=12790File:PIC Servo Controller.png2009-03-20T05:41:27Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12772Vision-based Cannon2009-03-20T05:25:50Z<p>Anthony Franco: /* Master PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
[[Media:Master Servo PWM Generator.c|Code for Master servo PWM generator and interfacing with Matlab]]<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
===Slave PIC===<br />
<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:Master_Servo_PWM_Generator.c&diff=12770File:Master Servo PWM Generator.c2009-03-20T05:24:43Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12764Vision-based Cannon2009-03-20T05:21:57Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
[[Media:Slave Servo PID Controller.c|Code for Slave servo PID controller]]<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:Slave_Servo_PID_Controller.c&diff=12758File:Slave Servo PID Controller.c2009-03-20T05:19:42Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12744Vision-based Cannon2009-03-20T05:02:32Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12743Vision-based Cannon2009-03-20T05:01:48Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
The Slave PIC is meant to interpret servo PWM signals and implement a Proportional-Integral-Derivative (PID) algorithm to drive a servo motor to its intended position. The incoming PWM signal comes in on CCP1, and the outgoing PWM signal goes out on CCP2 and C0 to an L298 H-Bridge chip which gives full bidirectional motor control. Because there are only two CCP pins available on the PIC18F4520, each servo motor must have its own dedicated slave PIC for driving.<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12735Vision-based Cannon2009-03-20T04:56:09Z<p>Anthony Franco: /* Master PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
<br />
The Master PIC is in charge of getting the servo positions via RS-232 communication with Matlab and converting them into PWM signals suitable for driving off the shelf servo motors. In the case of this project the servo pulse widths are fed into our custom PIC servo driver or "Slave" PIC's.<br />
<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12725Vision-based Cannon2009-03-20T04:47:34Z<p>Anthony Franco: /* Slave PIC */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
[[PIC Servo Controller|Main page about the PIC Servo controller]]<br />
<br clear=all><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=PIC_Servo_Controller&diff=12723PIC Servo Controller2009-03-20T04:44:05Z<p>Anthony Franco: </p>
<hr />
<div>=Blah=</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12720Vision-based Cannon2009-03-20T04:39:00Z<p>Anthony Franco: /* Circuits */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|right]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|right]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|right]]<br />
<br />
<br />
<br clear=all><br />
<br />
===Master PIC===<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br clear=all><br />
<nowiki>Insert non-formatted text here</nowiki><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12719Vision-based Cannon2009-03-20T04:37:58Z<p>Anthony Franco: /* Mechanics */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|left]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|left]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|left]]<br />
<br />
<br />
<br clear=all><br />
===Master PIC===<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br clear=all><br />
<nowiki>Insert non-formatted text here</nowiki><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|450px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|450px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12716Vision-based Cannon2009-03-20T04:35:58Z<p>Anthony Franco: /* Electronics */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
===Circuits===<br />
[[Image:MasterSlave Motor Control.png|Servo Drive and Control Circuit|thumb|450px|left]]<br />
<br />
[[Image:Fire Control.png|Nerf Gun Firing Circuit|thumb|450px|left]]<br />
<br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|450px|left]]<br />
<br />
<br />
<br clear=all><br />
===Master PIC===<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br clear=all><br />
<nowiki>Insert non-formatted text here</nowiki><br />
<br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|600px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|600px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|600px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:Fire_Control.png&diff=12683File:Fire Control.png2009-03-20T03:56:02Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:MasterSlave_Motor_Control.png&diff=12627File:MasterSlave Motor Control.png2009-03-20T03:23:38Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Vision-based_Cannon&diff=12513Vision-based Cannon2009-03-20T01:57:23Z<p>Anthony Franco: /* Overview */</p>
<hr />
<div>==Team Members==<br />
<br />
[[Image:SM_UsAndProject.jpg|right|Raw Image|thumb|400px]]<br />
<br />
* Scott Mueller (Mechanical Engineering, Class of 2010)<br />
* Tony Franco (Mechanical Engineering, Class of 2009)<br />
<br />
<br />
<br clear=all><br />
<br />
==Overview==<br />
<br />
<br />
The goal of this project was to use computer vision algorithms to identify targets and direct a Nerf gun to fire at them. The vision portion of the project utilized a web cam and Matlab's image acquisition and processing toolboxes to find and classify objects of interest. The Nerf gun was actuated using a pan & tilt assembly made from modified hobby servos using the PIC prototyping board as a dedicated PID servo controller. <br />
<br clear=all><br />
Watch A Video of the System in Action!<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=RsXYjYz_vM4| Servo Calibration Video]<br />
<br clear=all><br />
[http://www.youtube.com/watch?v=LRAXirfj4Uk| Target Shooting Video]<br />
<br />
==Vision System==<br />
The vision system was implemented in Matlab to take advantage of their image acquisition and image processing toolboxes.<br />
<br />
===Target Extraction===<br />
<br />
Targets were cut from colored foam and attached to a black background. Raw images were captured in RGB format, which takes the form of an [m,n,3] matrix. [http://en.wikipedia.org/wiki/RGB_color_model]. While targets could be identified in such an image, it is much faster to work with binary matrices. [http://en.wikipedia.org/wiki/(0,1)-matrix] To do this some scalar threshold is needed, such that any pixel in the raw image having a value greater than the threshold becomes 1 in the binary image and anything less becomes 0. Rather than a static threshold which would be affected by room lighting, a dynamic threshold based on the median image brightness is used. <br />
<br />
[[Image:SM_Main_RAW.bmp|right|Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*capture raw image<br />
<br clear=all><br />
<br />
[[Image:SM_Main_ROI.bmp|right|Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*select an ROI (region of interest) and turn any pixels outside of it off<br />
<br clear=all><br />
<br />
[[Image:SM_Main_Binary.bmp|right|Binary Image|thumb|400px]]<br />
<br />
<br />
<br />
*create binary image based on threshold<br />
<br clear=all><br />
*create a label matrix (identifies regions of interconnected pixels)<br />
<br />
*remove small objects (pixel threshold)<br />
<br clear=all><br />
<br />
[[Image:SM_Ball_binMask.bmp|right|Binary Mask of Object In Image|thumb|400px]]<br />
<br />
<br />
<br />
*create list of targets: fill data structure with pertinent target properties (area, centroid, perimeter,shape,color,binary mask)<br />
<br clear=all><br />
<br />
<br />
[[Image:SM_Main_Label.bmp|right|Shape and Color Classified Objects|thumb|400px]]<br />
<br />
<br />
<br />
*classify target shapes and colors<br />
<br clear=all><br />
<br />
===Servo Calibration===<br />
<br />
Since the camera and the Nerf gun are not coaxial a method of mapping servo angles to pixel positions in the image needs to be implemented. This is done by removing all targets from the background so that a laser on the pan/tilt assembly is easily visible. By moving the servos through various angles and finding the centroid of the laser on the background a lookup table can be created. Interpolation can then be used to determine the appropriate servo angles for a given pixel position of a target.<br />
<br />
[[Image:SM_ServoCalibration_RAW.bmp|right|Servo Calibration: Raw Image|thumb|400px]]<br />
<br />
<br />
<br />
*This image is the raw image of the black background with some extraneous background. The laser is the white dot in the lower left hand corner.<br />
<br clear=all><br />
<br />
<br />
<br />
[[Image:SM_ServoCalibration_selectROI.bmp|right|Servo Calibration: Selecting ROI|thumb|400px]]<br />
<br />
<br />
<br />
*The ROI (region of interest) has been selected over the black background only.<br />
<br clear=all><br />
<br />
[[Image:SM_ServoCalibration_position1.bmp|right|Servo Calibration: Laser Identified|thumb|400px]]<br />
<br />
<br />
<br />
*Beginning the servo calibration routine, the centroid of the laser is found and marked with a blue '*'.<br />
<br clear=all><br />
<br />
===Matlab Code===<br />
<br />
For brevity the full code is not shown here. For file descriptions and comments see files.<br />
<br />
*[[media:SM_Main.m|Main Program]]<br />
*[[media:SM_ServoCalibration.m|Servo Calibration]]<br />
*[[media:SM_GetShape.m|Shape Classification]]<br />
*[[media:SM_Fire.m|Fire The Nerf Gun]]<br />
*[[media:SM_PanTilt.m|Send Pan/Tilt Servo Positions]]<br />
*[[media:SM_Tx.m|Serial Ouput]]<br />
<br />
==Electronics==<br />
The electrical system for this project consisted of a custom developed master/slave servo controller. Each actuator is controlled directly by a slave system that monitors a feedback potentiometer and implements PID control. Each slave in turn receives a position command from a master PIC, which itself is controlled by Matlab running on a PC. <br />
<br clear=all><br />
[[Image:SM_PIC_Boards.jpg|Master, 2 Slaves, Fire Control PICs|thumb|600px]]<br />
===Master PIC===<br />
[[SM_Matlab_Servo_Controller.c‎]]<br />
<br />
===Slave PIC===<br />
<br />
<br clear=all><br />
==Mechanics==<br />
<br />
The nerf gun used was a [http://www.dreamcheeky.com/index.php?pagename=product&pid=1: Dream Cheeky USB Missile Launcher] which we modified to fit our own actuators into. The actuators were [http://www.futaba-rc.com/servos/specs-lineart/specs-futm0004.html: Futaba 3004 Servo]. We removed the control circuitry and wired the potentiometer and motor to the slave PIC controllers. Then we fitted the servos into the Missile Launcher housing. The gun firing mechanism consisted of a spring actuated piston which was driven by a sector gear. A microswitch was tripped after the gun fired and the piston returned to the relaxed position. We simply used a transistor to turn the motor on and off with a PIC and used the input from the microswitch to trigger an external interrupt to shut the motor off.<br />
<br />
<br />
[[Image:SM_Target.jpg|Targets|thumb|600px]]<br />
<br clear=all><br />
[[Image:SM_Gun_Camera_PIC_Setup.JPG|Camera Gun and PIC Assembly|thumb|600px]]<br />
<br clear=all><br />
[[Image:SM_PanTilt_Open.jpg|The pan/tilt assembly opened|thumb|600px]]<br />
<br clear=all><br />
<br />
==Results==<br />
<br />
The vision algorithms themselves worked very well. We were able to extract targets from the background and identify their centroid, shape and color and store them in a data structure as a list of targets. However as targets got farther away from the center of the image the shape got distorted by the curvature of the camera lens, throwing off the area/perimeter ratio used to determine shape. The servo calibration routine also worked well and the interpolated servo angles closely matched the actual pixel center of the targets. We had some problems getting the PID coefficients on the slave PICs adjusted properly which resulted in some error in the servo positioned which in turn was reflected in the servo calibration routine. <br />
<br />
The master/slave PIC arrangement worked very well and the slave PICs were able to measure the incoming signal pulsewidth +- 1us. Communication between the master PIC and Matlab also worked well. Unfortunately the function to fire the nerf gun from Matlab did not work, for reasons unknown. The PIC function to fire the gun via a push button worked fine, but calling that routine when it received serial data did not. We tried different PICs, different baud rates (19200 and 9600 bps) and different USB-FTDI cables with no success. For our demonstration we manually fired the gun with the push button.<br />
<br />
==Future Work==<br />
<br />
A more precisely made pan/tilt mechanism with more precise potentiometers would have improved accuracy/repeatability of the system. Lens distortion could be compensated for by applying some sort of camera calibration routine to map pixels to a plane rather than the spherical surface of the lens.<br />
<br />
==References==<br />
<br />
*[http://en.wikipedia.org/wiki/Computer_vision/: Computer Vision]<br />
*[http://www.mathworks.com/products/image/: Matlab Image Processing Toolbox]<br />
*[http://en.wikipedia.org/wiki/Servo_drive/: Servo Drive]<br />
*[http://en.wikipedia.org/wiki/Pulse-width_modulation/: Pulse Width Modulation(PWM)]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10658Characterizing the response of a solenoid2009-02-12T16:13:54Z<p>Anthony Franco: /* Oscilloscope Graphs */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
The objective of this experiment was to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply. We used an accelerometer attached to the solenoid plunger and a small return spring to return the plunger to its original position when the solenoid was unpowered. By simultaneously tracking the on-off pulsed forcing of the solenoid and the acceleration responses of the plunger we were able to interpret our results.<br />
<br />
<br clear="all"><br />
<br />
== Circuit ==<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
The bench top function generator was able to drive the solenoid at different frequencies and with different PWM signals, but unable to provide enough current to move the plunger with much force. Therefore we used a single MOSFET driving circuit with the function generator providing the gate voltage and switching the solenoid on and off using the separate power supply which was able to give us the needed current to get a noticeable response. Because of the inductance of the solenoid coil and the fast switching on and off, a flyback diode was used. <br />
<br />
<br />
<br />
<br />
<br />
<br />
The ADXL321EB accelerometer evaluation board (spec sheet here [[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]) had three simple pin connections as well. One pin for +5V, one for ground, and because of the orientation was used for the evaluation board, one to track the Y-axis acceleration.<br />
<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
<br />
<br />
=== Very Low Frequency (<10Hz) Response ===<br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
===Low Frequency (<100 Hz) Response===<br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
===Response to Varying Driving Duty Cycle===<br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
===Response to Varying Driving Amplitude===<br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
===Resonance (~20Hz)===<br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
===Response of Driving Near Resonance===<br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10657Characterizing the response of a solenoid2009-02-12T15:42:32Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
The objective of this experiment was to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply. We used an accelerometer attached to the solenoid plunger and a small return spring to return the plunger to its original position when the solenoid was unpowered. By simultaneously tracking the on-off pulsed forcing of the solenoid and the acceleration responses of the plunger we were able to interpret our results.<br />
<br />
<br clear="all"><br />
<br />
== Circuit ==<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
The bench top function generator was able to drive the solenoid at different frequencies and with different PWM signals, but unable to provide enough current to move the plunger with much force. Therefore we used a single MOSFET driving circuit with the function generator providing the gate voltage and switching the solenoid on and off using the separate power supply which was able to give us the needed current to get a noticeable response. Because of the inductance of the solenoid coil and the fast switching on and off, a flyback diode was used. <br />
<br />
<br />
<br />
<br />
<br />
<br />
The ADXL321EB accelerometer evaluation board (spec sheet here [[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]) had three simple pin connections as well. One pin for +5V, one for ground, and because of the orientation was used for the evaluation board, one to track the Y-axis acceleration.<br />
<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10656Characterizing the response of a solenoid2009-02-12T15:32:49Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
The objective of this experiment was to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply. We used an accelerometer attached to the solenoid plunger and a small return spring to return the plunger to its original position when the solenoid was unpowered. By simultaneously tracking the on-off pulsed forcing of the solenoid and the acceleration responses of the plunger we were able to interpret our results.<br />
<br />
<br clear="all"><br />
<br />
== Circuit ==<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
The bench top function generator was able to drive the solenoid at different frequencies and with different PWM signals, but unable to provide enough current to move the plunger with much force. Therefore we used a single MOSFET driving circuit with the function generator providing the gate voltage and switching the solenoid on and off using the separate power supply which was able to give us the needed current to get a noticeable response. Because of the inductance of the solenoid coil and the fast switching on and off, a flyback diode was used. <br />
<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10653Characterizing the response of a solenoid2009-02-12T15:23:56Z<p>Anthony Franco: /* Overview */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
The objective of this experiment was to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply. We used an accelerometer attached to the solenoid plunger and a small return spring to return the plunger to its original position when the solenoid was unpowered. By simultaneously tracking the on-off pulsed forcing of the solenoid and the acceleration responses of the plunger we were able to interpret our results.<br />
<br />
<br clear="all"><br />
<br />
== Circuit ==<br />
<br />
A function generator provided a square wave to saturate the base of an NPN Mosfet to drive the solenoid. The duty cycle and frequency applied to the solenoid are controlled by varying parameters on the function and the applied voltage was adjusted on the power supply for the solenoid.<br />
<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10652Characterizing the response of a solenoid2009-02-12T15:23:01Z<p>Anthony Franco: /* Overview */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
The objective of this experiment was to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply. We used an accelerometer attached to the solenoid plunger and a small return spring to return the plunger to its original position when the solenoid was unpowered. By simultaneously tracking the on-off pulsed forcing of the solenoid and the acceleration responses of the plunger we were able to interpret our results.<br />
<br />
== Circuit ==<br />
<br />
A function generator provided a square wave to saturate the base of an NPN Mosfet to drive the solenoid. The duty cycle and frequency applied to the solenoid are controlled by varying parameters on the function and the applied voltage was adjusted on the power supply for the solenoid.<br />
<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10649Characterizing the response of a solenoid2009-02-12T15:15:21Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
The objective of this experiment is to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply.<br />
<br />
== Circuit ==<br />
<br />
A function generator provided a square wave to saturate the base of an NPN Mosfet to drive the solenoid. The duty cycle and frequency applied to the solenoid are controlled by varying parameters on the function and the applied voltage was adjusted on the power supply for the solenoid.<br />
<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10648Characterizing the response of a solenoid2009-02-12T15:13:46Z<p>Anthony Franco: /* Overview */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
The objective of this experiment is to understand the behavior of a solenoid at various input frequencies, duty cycles and voltages. The PIC was not needed for this experiment at all because independent adjustment of all three parameters was capable using the bench top function generator and power supply.<br />
<br />
== Circuit ==<br />
<br />
A function generator provided a square wave to saturate the base of an NPN Mosfet to drive the solenoid. The duty cycle and frequency applied to the solenoid are controlled by varying parameters on the function and the applied voltage was adjusted on the power supply for the solenoid.<br />
<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
[[Image:Accelerometer Rig.JPG|right|thumb|300px|The Accelerometer Rig]]<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
[[Image:Project Set Up.JPG|right|thumb|400px|Set up for the lab]]<br />
<br />
<br clear="all"><br />
<br />
== Oscilloscope Graphs ==<br />
The upper trace is the accelerometer, the lower trace is the voltage across the solenoid. On the accelerometer trace 0g corresponds with 2.5V, +18g is 0V and -18g is 5V. <br />
<br />
[[Image:15V3Hz50%.JPG|right|thumb|500px|3 Hz Driving]]<br />
<br />
<br />
<br />
'''Region A-B-C-D'''<br />
The accelerometer reading near A indicates a downward acceleration. This coincides the falling edge of the square wave, and the solenoid becomes unpowered which indicates some unusual effect.<br />
<br />
The region above the baseline at B indicates an upward acceleration caused by the return spring. The subsequent oscillation from B-C-D is typical damped oscillatory motion. Since the solenoid is unpowered in this region the result makes sense.<br />
<br />
'''Region E-F-G'''<br />
Since E coincides with the rising edge of the square wave and the solenoid is powered the upward acceleration at E is also unexplained. The region E-F which shows a downward acceleration is consistent with the solenoid pulling the plunger down with a positive jerk. At point F, maximum downward acceleration the return spring is compressed enough to induce negative jerk. The region near G of upward acceleration (above baseline) is the result of the plunger overshooting equilibrium between the spring compression and the solenoid until the solenoid can retake control and stop the oscillation. <br />
<br />
<br clear="all"><br />
<br />
These scope traces show the erratic vibrations at low frequencies. At these frequencies the solenoid plunger hits both end stops. The erratic acceleration is due to the spring becoming completely unloaded as the plunger exits the solenoid and the subsequent recontact between the plunger and spring.<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz). At this higher frequency the plunger retains contact with the return spring and does not hit either end stop. Note that at 75% duty cycle the acceleration profile approaches a square wave. <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]<br />
<br />
<br clear="all"><br />
<br />
[[Image:Resonance.JPG|right|thumb|500px|Resonance]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
Resonance was observed at 20Hz resulting in very high downward (negative) accelerations indicating contact between the plunger and the solenoid stop. From A to B the plunger is accelerating upward with a negative jerk. Since the solenoid is unpowered in this region this indicates that gravity is taking control of the plunger after losing contact with the spring. The acceleration from B-C rapidly decays to baseline because the square wave voltage across the solenoid goes high and the solenoid pulls the plunger downward, compressing the spring. Region C-D occurs under a powered solenoid which accelerates the plunger downward with positive jerk. The ~11g reading (1.5V swing) at D indicates the plunger hits the lower stop. The rebound off the lower stop causes the spring to decompress quickly over D-E, propelling the plunger beyond the spring.<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the response just before, just after, and at the resonant frequency of 20Hz<br />
<br />
[[Image:15V15Hz50%(JBResonance).JPG|left|thumb|300px|Just Before Resonance]]<br />
[[Image:15V20Hz50%(Resonance).JPG|left|thumb|300px|Resonance]]<br />
[[Image:15V40Hz50%(JAResonance).JPG|left|thumb|300px|Just After Resonance]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10289Characterizing the response of a solenoid2009-02-11T06:03:09Z<p>Anthony Franco: /* Code */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
== Circuit ==<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br clear="all"><br />
<br />
== Code ==<br />
<br />
These scope traces show the erratic vibrations at low frequencies<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz) <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying driving amplitude at constant frequency (300Hz) and duty cycle (50%)<br />
<br />
[[Image:15V300Hz50%(small).JPG|left|thumb|300px|15 V Amplitude]]<br />
[[Image:20V300Hz50%(small).JPG|left|thumb|300px|20 V Amplitude]]<br />
[[Image:24V300Hz50%(small).JPG|left|thumb|300px|24 V Amplitude]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:24V300Hz50%25(small).JPG&diff=10288File:24V300Hz50%(small).JPG2009-02-11T05:59:39Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:20V300Hz50%25(small).JPG&diff=10287File:20V300Hz50%(small).JPG2009-02-11T05:59:24Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:15V300Hz50%25(small).JPG&diff=10286File:15V300Hz50%(small).JPG2009-02-11T05:59:10Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10285Characterizing the response of a solenoid2009-02-11T05:56:15Z<p>Anthony Franco: /* Code */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
== Circuit ==<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br clear="all"><br />
<br />
== Code ==<br />
<br />
These scope traces show the erratic vibrations at low frequencies<br />
<br />
[[Image:15V10Hz50%(small).JPG|left|thumb|300px|10 Hz Driving]]<br />
[[Image:15V25Hz50%(small).JPG|left|thumb|300px|25 Hz Driving]]<br />
[[Image:15V50Hz50%(small).JPG|left|thumb|300px|50 Hz Driving]]<br />
<br />
<br clear="all"><br />
<br />
These scope traces show the effects of varying the duty cycle with constant amplitude (24V) and frequency (200Hz) <br />
<br />
[[Image:24V200Hz25%(small).JPG|left|thumb|300px|25% Duty Cycle]]<br />
[[Image:24V200Hz50%(small).JPG|left|thumb|300px|50% Duty Cycle]]<br />
[[Image:24V200Hz75%(small).JPG|left|thumb|300px|75% Duty Cycle]]</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:15V25Hz50%25(small).JPG&diff=10284File:15V25Hz50%(small).JPG2009-02-11T05:51:39Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:15V50Hz50%25(small).JPG&diff=10283File:15V50Hz50%(small).JPG2009-02-11T05:49:45Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:15V10Hz50%25(small).JPG&diff=10282File:15V10Hz50%(small).JPG2009-02-11T05:49:18Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:24V200Hz75%25(small).JPG&diff=10281File:24V200Hz75%(small).JPG2009-02-11T05:42:22Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:24V200Hz50%25(small).JPG&diff=10280File:24V200Hz50%(small).JPG2009-02-11T05:42:09Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:24V200Hz25%25(small).JPG&diff=10279File:24V200Hz25%(small).JPG2009-02-11T05:41:50Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10278Characterizing the response of a solenoid2009-02-11T05:39:24Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
== Circuit ==<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br clear="all"><br />
<br />
== Code ==</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=Characterizing_the_response_of_a_solenoid&diff=10277Characterizing the response of a solenoid2009-02-11T05:38:33Z<p>Anthony Franco: /* Circuit */</p>
<hr />
<div>== Original Assignment ==<br />
<br />
Your job is to characterize the response of a solenoid to on-off pulsed forcing. The solenoid should be equipped with a return spring so that the solenoid returns to a home position when the coil is de-energized.<br />
<br />
You should provide the user with the ability to control three parameters of the on-off pulsed forcing: the frequency of the on-off pulsed forcing, the duty cycle, and the amplitude (the voltage or current applied to the coil when it is energized). You will mount an [[Accelerometers|accelerometer]] on the shaft of the solenoid and use an oscilloscope to simultaneously look at the control voltage to the solenoid and the acceleration of the solenoid. Try frequencies from 10 Hz to hundreds of Hz. For what frequencies, duty cycles, and amplitudes does the solenoid shaft hit stops, and for what values do you get approximate square wave acceleration profiles? Summarize your results in text and post clear images of the oscilloscope for a few representative choices.<br />
<br />
Note: your PIC may not be involved in this assignment at all. You could use a function generator to generate the frequency and duty cycle you want, and use the amplitude to (perhaps) control a transistor operating in the linear regime to deliver different amounts of current to the solenoid. It may make sense to always energize the coil a little bit, even in the "off" state, so that the return spring is always in a bit of tension.<br />
<br />
<br />
<br />
<br />
<br />
== Overview ==<br />
<br />
== Circuit ==<br />
<br />
Accelerometer:<br />
[[http://hades.mech.northwestern.edu/wiki/index.php/Image:AnalogDevices_ADXL321EB.pdf]]<br />
<br />
[[Image:Solenoid_Driver_Lab_5.bmp|right|thumb|300px|Solenoid Driving Circuit]]<br />
<br />
== Code ==</div>Anthony Francohttps://hades.mech.northwestern.edu//index.php?title=File:Solenoid_Driver_Lab_5.bmp&diff=10276File:Solenoid Driver Lab 5.bmp2009-02-11T05:23:48Z<p>Anthony Franco: </p>
<hr />
<div></div>Anthony Franco