Friday, January 27, 2012

Torpedo Awayyyyyyy!!!

Here is the latest update for the torpedo that will be mounted and operated by the AUV.

Part 1: Circuit
Parts list:
(1) PICAXE micro controller
(1) momentary button
(x) necessary resistors
(1) LED
(2) transistors
(1) back EMF suppression diode
(1) D/C motor
Let me give a brief explanation for a few items. the micro controller is necessary because i wish to have an LED allowing me to be able to check the completion of the circuit. The momentary button will be mounted in the tip of the torpedo so when it hit something it will stop the program and motor.
Part 2: Code
symbol motor = 1
main:
readadc 4,b0 sertxd("msg",#b0,cr,lf)
pause 1000
if b0 >100 then motoron
if b0 <100 then killswitch
goto main

motoron:
high motor
goto main

killswitch:
sertxd("kill",#b0,cr,lf)
low motor
end

Above is the code i wrote for my micro controller PICAXE. The logic of the program is to continually have power fed to the circuit until the momentary button is activated. Once the momentary button is activated the micro controller will execute 'killswitch' which kills all circuit protocol and power to the entire system.
Part 3: Mechanics
I havent settled on a tube to mount all my components in yet. Originally i wanted to mount all the components into a cigar tube, however discovering that i will need to have two separate power sources(one for the micro controller and one for the motor) and an added safety measure compartment to keep water away from all the electronics, i had to re-think the final product. Currently I'm leaning towards a fortified piece of plastic pipe, but i'm also investigating other options like different types of metal tubes. I have pictured right now is how i will be attaching the drive shaft to the motor as well as the propeller. My "universal" joint is plastic tubing that fits snugly around the drive shaft and the D/C motor shaft. I also use the same plastic tubing to ensure a tight around my drive shaft propeller. For the portion of the drive shaft that will pass through the hull to water i have obtained a hollow shaft that fits snug around the drive shaft. The fit is almost bearing like so i think with a little grease in side the tube PLUS the safety compartment that will separate the water from the electronic compartment.
******UPDATE******
the torpedo circuit is complete and works properly.
the code that is written for the circuit is executing properly.
the step before testing is to mount the components in an air tight hull.
and the final step before freeing the design of the torpedo is choosing a technique to integrate the torpedo into the AUV

Tuesday, January 24, 2012

Here is the prototype for the new Heads Up Display. Andy and I worked on a nice little augmentation of the Otter Box which we will share at the next meeting.
from math import *
from visual import *
import serial

######################################################################
#Opening the serial port for the compass output
######################################################################
try:
    compass.close()
except:
    print "compass ready"
    
try:
    compass = serial.Serial(2,baudrate=9600, bytesize=8,parity = 'N',stopbits = 1,timeout=None, xonxoff=0, rtscts=0)
    compass.open
    output = compass.readline()
    print(output) 
except:
    print('you fail')
######################################################################
    
RightSideWindow = display(x=0, y =0, witdth = 600, height = 600,scale =(1,1,1) ,background = (.05,.05,.05), autoscale = false)
RightSideWindow.range  = 10
headingVect = arrow(pos =(0,0,0), axis = (2,0,0), shaftwidth = 1, color = (.2,.7,.7))
northBox = box(pos=(0,3,0), height = 2,width = .1,length = .1, color = (1,1,1))    
southBox = box(pos=(0,-3,0), height = 2,width = .1,length = .1, color = (1,1,1))    
eastBox = box(pos=(3,0,0), height = .1,width = .1,length = 2, color = (1,1,1))    
westBox = box(pos=(-3,0,0), height = .1,width = .1,length = 2, color = (1,1,1))    
northLabel = label(pos = (0,4.5,0),text = 'N')
southLabel = label(pos = (0,-4.5,0),text = 'S')
eastLabel = label(pos = (4.5,0,0),text = 'E')
northLabel = label(pos = (-4.5,0,0),text = 'W')
northeast = box(pos = (2.5*cos(pi/4),2.5*sin(pi/4),0),axis = (-cos(pi/4),sin(pi/4),0),height = 1,width = .1,length = .1)
northwest = box(pos = (-2.5*cos(pi/4),2.5*sin(pi/4),0),axis = (cos(pi/4),sin(pi/4),0),height = 1,width = .1,length = .1)
southwest = box(pos = (-2.5*cos(pi/4),-2.5*sin(pi/4),0),axis = (-cos(pi/4),sin(pi/4),0),height = 1,width = .1,length = .1)
northwest = box(pos = (2.5*cos(pi/4),-2.5*sin(pi/4),0),axis = (cos(pi/4),sin(pi/4),0),height = 1,width = .1,length = .1)

    
headingLabel = label(pos = (0,6,0), text = 'HEADING')    
    
    
while 1:
    output = compass.readline()
    heading = (double(output)-9)*pi/180.
    x = -cos(heading)*2
    y = sin(heading)*2
    headingVect.axis = (x,y,0)

Friday, January 20, 2012

Pinwheel encoder test

The arduino code I used for testing:
int trigs = 0;
void setup()
{
pinMode(13, OUTPUT);
attachInterrupt(0, ledblink, CHANGE);
Serial.begin(9600);
}

void loop()
{
delay(100);
}

void ledblink()
{
trigs++;
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
Serial.println(trigs);
}
....and a quick video:

Thursday, January 12, 2012

Camera Water Proofing part II

Here is the finished version of the waterproofed camera.


Here is the camera looking at the TV!

Here is a front view!

e
Currently the Camera is sitting in water for its first water test. As far as the electronics go, everything is running perfectly. As far as the video is concerned... it is not so good. It may be that the camera only has 12 inches of water between it and the furthest object, but nothing is in focus at that range.
I think that further testing in a larger body of water is necessary before proceeding to waterproof the other two cameras.

A complication arose during the potting process which may be responsible for the blur. Upon inspection of the finished product, it was noted that resin had seeped into the air gap between the case and the lens. As this would interfere with the video, I drilled out the air gap and cleaned the entire area. Luckily, the resin which seeped in was lacking in catalyst and was still in its liquid phase.

After the cleaning procedure, the camera was tested in air and found to be free of any optical defects. Water immersion revealed the focal problem, which may stem from the main lens being immersed in water as opposed to air.

Two possible conditions may apply.
The focal length has changed due to the immersion in water, and objects at distance will be in focus.
No objects will be in focus, and an additional layer of plastic will need to be added to reestablish an air gap.

Testing on Saturday will determine the proper course of action. Bardia's place, 9 am. If a solution is found, the other two cameras will be waterproofed after testing.

Wednesday, January 11, 2012

Camera Water Proofing

Water Proofing a Camera for Depth:
This I.C. Live Camera is going to become an under water camera, courtesy of some casting resin, hot glue and a plastic box. A link to explain the basics can be found here.

Now to crack the case and extract the juicy interior!
Now, much like the hermit crab, this camera can move on to better housing. But first we need to give it some juice. In order to test the video feed and focus the camera, I attached this Motorola 5 volt power supply and hooked up the video output to an old analog TV. 



Once the Camera was appropriately focused, I sealed the focusing ring with hot glue. Additionally I sealed all components with silicone insulation. Here is what it looks like after the sealant is applied.



Once that stuff dried, I attached the top from a clear plastic box to the camera's plastic case.

The rest of the box has two bolts drilled through the sides and then sealed. Additionally, and not captured in photograph, a length of PVC was added to the housing so that this camera could interface with standard PVC fittings.

Once the top and bottom of the plastic box were mated, I drilled a small hole to pull the wires through and filled the entire box with resin. It is currently curing outside so that my house doesn't fill with resin fumes.
Once the resin cures, I will take video showing the performance of the camera and test it in water to make sure that it still functions in the manner that we need.


Monday, January 9, 2012

Robo Sub 2012 Logo


Now announcing the Robo Sub crew for the upcoming AUVSI 2012 competition complete with Logo designed by Ms. Simone Wick.

How to use the syntax highlighting

I've edited the template for this blog so you can now use syntax highlighting/formating.
When you want to post your code, go to Edit HTML, and paste this before your code:
<pre class="alias" name="code">
 where "alias" is the name of the programming language you're highlighting.
For example, if you were posting python, you would put
<pre class="python" name="code">
If you have really long code you can attach ":collapse" to the alias and the code will only show up if the viewer clicks "Expand Source"
A collapsed C++ would look like this:
<pre class="cpp:collapse" name="code">
Here's a list of the languages and aliases:
http://code.google.com/p/syntaxhighlighter/wiki/Languages

Of course, remember to close your html tags with </pre> at the end of your code.

ROV joystick control

Here's the code i'm using on the arduino for the joystick control
#include <Servo.h>
int deadzone = 15;
int rev1 = 2;
int rev2 = 3;
int rev3 = 4;
int rev4 = 5;
int joyPin1 = 0;                 // slider variable connecetd to analog pin 0
int joyPin2 = 1;                 // slider variable connecetd to analog pin 1
int joyPin3 = 2;
int servospd1 = 1;
int servospd2 = 1;
int servospd3 = 1;
int servospd4 = 1; 
int axis1[4] = {0, 600 , 755 , 970}; //y-axis {value, min, center, max}
int axis2[4] = {0, 590 , 780 , 1023}; //x-axis
int axis3[3] = {0, 400, 700};
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;

void setup() 
{
  pinMode(rev1, OUTPUT);              // initializes digital pins 0 to 7 as outputs
  pinMode(rev2, OUTPUT);
  pinMode(rev3, OUTPUT);
  pinMode(rev4, OUTPUT);
  myservo1.attach(12);
  myservo2.attach(11);
  myservo3.attach(10);
  myservo4.attach(9);
  Serial.begin(9600);
}

int forward(int data) {
  return ( ( data - 190 ) / 4.1111111111 );
}

int reverse( int data ){
  return ( 180 - ( data - 90 ) / .2222222222222 );
}

void loop() 
{
  // reads the value of the variable resistor 
  //axis1 = treatValue( analogRead( joyPin1 ) );
  
  myservo1.write( abs(servospd1 - servospd2) );
  myservo2.write( abs(servospd1 + servospd2) );
  myservo3.write( servospd3 );
  //myservo4.write( servospd4 );
  
//////LEFT MOTOR /////  
  if( axis1[0] >= (deadzone) )
  {
    servospd1 = ( float(axis1[0]) * 180 / (axis1[3]-axis1[2]) );\
  }
  else if( axis1[0] <= (-deadzone) )
  {
    servospd1 = ( float(axis1[0]) * 180 / (axis1[2]-axis1[1]) ); 
  }
  else
  {
    servospd1 = 0;
  }
/////RIGHT MOTOR/////
  if( axis2[0] >= (deadzone) )
  {
    servospd2 = ( float(axis2[0]) * 180 / (axis2[3]-axis2[2]) );
  }
  else if( axis2[0] <= (-deadzone) )
  {
    servospd2 = ( float(axis2[0]) * 180 / (axis2[2]-axis2[1]) ); 
  }
  else
  {
    servospd2 = 0;
  }
///////VERTICAL MOTOR//////
  if( axis3[0] > 1024 )
  {
    servospd3 = 90;
    digitalWrite(rev3, LOW);
  }
  else if( 850 < axis3[0] && axis3[0] < 875)
  {
    servospd3 = 90;
    digitalWrite(rev3, HIGH);
  }
  else if( 690 < axis3[0] && axis3[0] < 720 )
  {
    servospd3 = 0;
    digitalWrite(rev3, LOW);
  }
////////////
  if ((servospd1 - servospd2) < 0)
  {   
    digitalWrite(rev1, HIGH);
  }
  else
  {
    digitalWrite(rev1, LOW);
  }
  if ((servospd1+servospd2) < 0)
  { 
    digitalWrite(rev2, HIGH); 
  }
  else
  {
    digitalWrite(rev2, LOW);
  }
  
  for(int i=0; i<10; i++)
  {
    axis1[0] += analogRead( joyPin1 );
    axis2[0] += analogRead( joyPin2 );
    axis3[0] += analogRead( joyPin3 );
    myservo1.write( abs(servospd1 - servospd2) );
    myservo2.write( abs(servospd1 + servospd2) );
    myservo3.write( servospd3 );
    myservo4.write( servospd4 );
    delay(7);
  }
  axis1[0] = ( float(axis1[0]) / 10 ) - axis1[2];
  axis2[0] = ( float(axis2[0]) / 10 ) - axis2[2];
  axis3[0] = ( float(axis3[0]) / 10 );
  
  Serial.print( axis1[0] );
  Serial.print( "\t" );
  Serial.print( axis2[0] );
  Serial.print( "\t" );
  Serial.print( axis3[0] );
  Serial.print( "\n" );
  /*
  Serial.print( servospd1 );
  Serial.print( "\t" );
  Serial.println( servospd2 );  
*/
  //delay(100); 
} 
derp

Thursday, January 5, 2012

Heading using a Magnetometer and Accelerometer

In any navigation project, it's important for us to determine the heading at any given time. Our weapon of choice is an LSM303DLM magnetometer and accelerometer module. Pololu has provided the libraries for use with the Arduino. It includes all the necessary functions for us to determine heading, so minimal work needs to be done.
We're experiencing drift between power cycles, so self tests will probably be done on power up for best accuracy. Aside from that, the data readings appear to have very little noise and is rather consistent. The next few steps are to calibrate the readings so all directions read correspond to the physical orientation and to integrate it with the rest of the ROV/AUV. Based on rough readings and a traditional compass, the headings are quite accurate.

The libraries can be found here:
LSM303DLM

Tuesday, January 3, 2012

Access to simulation code via github

here is a link to the repository I created for sharing the robosub code.
https://github.com/walkerbrianpatrick/Mt.-SAC-robosub-2012
I do not know how to add collaborators yet, but I'm sure we could figure it out if you are interested in working on the code.

video of robosub in action

This video is from the first water test of robosub. It is mostly successful, however one of the motor shrouds falls off during the test. 


Upcoming events

Timeline for upcoming Robosub activities:

Wednesday, Jan 4th.
Andy will be finishing up some chassis connectors for the test on Thursday

Thursday, Jan 5th.
Bardia, Jay Jay, and Brian will be meeting at Mt. SAC at 9 am. Next, we will be  picking up some plate steel and pipes from Ace Metal Supply in Chino.
expected end time: 10-10:30
After that, we will fabricate 2 new motor mounts and attach them to the sub.
expected end time 12:30
Testing in Bardia's pool to begin around 2 pm.
If new motor mounts cause the submarine to be unbalanced, extra weights will be attached in the front.
Ideally driving the submarine and shaping foam in order to compensate for drag.

Navigation Framework

      As mentioned at the meeting earlier today, a three dimensional model space makes navigation easier. In order to illustrate that point, this model was constructed. The gray cylinder represents the submarine, and the arrows which hover around it represent various vectors describing thrust, climb, and total velocity.
      The submarine attempts to travel between the purple spheres using only vertical climbing vectors, turning in the horizontal plane, and forward thrust (defined as in the direction of the viewing window, or whitish part of the cylinder). As can be seen in the video, the model is able to successfully navigate between the three chosen locations, although slowly. 
      A key component to the success of the navigation simulation was the inclusion of drag and its effect on velocity, without which the sub continues to drift past its objective and crash into the wall. A more complicated version of the thrust control and climb control algorithms can be constructed so that the trip can be completed in shorter time, but would require some predictive deceleration. I have an idea about how to do this, and will attempt to include it in the next version.