incorporating GPS in a pan/tilt mount

Hi

So basically I want to create a pan/tilt mount for an RC UAV camera pod. Possibly even a live video feed.
But instead of constantly having to move the camera around, I want to make an Arduino-powered pan/tilt system, that automatically would move the camera to a preset GPS location, and altitude above sea level. I have the electronics figured out, but I'm having problems with the code. I'm thinking sin/cos/tan formulas...

I'm going to be using an AtMega328 with OptiBoot and the rest of the parts will be bought at Sparkfun:
For the altimeter

And the GPS

For the prototype I will be using the breakout boards, but in the end, I will make it as small as possible(thinking ~20*30mm) using an FTDI. If I can make that small, I'll receive a total of 16 PCB's. If you help me or even join the project, there will probably be to many boards, for me to use.... If you know where I'm going at :wink:

Simon Madsen

How are you moving the camera a pan/tilt mount won't change its lat/long or altitude.

Mark

The BMP085 you specc'ed has typical error of +/-1hPa which corresponds to almost +/-10 meters of difference in density altitude. How does the error in density altitude affect your system, the error causes your system to have an error of +/- 10 m so when the calculations are made to calculate the pointing direction of the pan tilt system. There will also be error in Lat and Lon from the GPS uncertainty so this will cause an error in the pan tilt calculations.

Are these errors too large? Whether the error will cause problems for you is dependent upon the distance to the objects of interest and the field of view of your camera, to name a few.

wade

holmes4:
How are you moving the camera a pan/tilt mount won't change its lat/long or altitude.

Mark

The camera is going to be mounted on an RC-type airplane.

wwbrown:
The BMP085 you specc'ed has typical error of +/-1hPa which corresponds to almost +/-10 meters of difference in density altitude. How does the error in density altitude affect your system, the error causes your system to have an error of +/- 10 m so when the calculations are made to calculate the pointing direction of the pan tilt system. There will also be error in Lat and Lon from the GPS uncertainty so this will cause an error in the pan tilt calculations.

Are these errors too large? Whether the error will cause problems for you is dependent upon the distance to the objects of interest and the field of view of your camera, to name a few.

wade

The camera will not be zoomed in, so it will have a large area of view, and thus the errors wont matter that much, since the plane will be at least 70m above ground level

holmes4:
How are you moving the camera a pan/tilt mount won't change its lat/long or altitude.

Mark

I'm not sure of what you mean, but the camera will be moved/rotated on a dual axis setup. This should allow it to be "pointed" at the preset target location.

simo9836:
that automatically would move the camera to a preset GPS location, and altitude above sea level.

So you want to have the Arduino find its own position using GPS and orientation using a gyro and compass, then calculate the relative bearing and elevation to your target position? That's a pretty neat idea. Just compensating for changes in the vehicle orientation will be quite tricky, I suspect. In effect you'd be making a steadycam. Then you need to do a bit of trigonometry to calculate the direction of your target point. GPS does not give you very good resolution so it will be a bit notchy. If that's important to you you could probably use interpolation to smooth that out, and if you have a gyro that would give you an even better solution.

@PeterH

I was planning on using a gyro and a compass to calculate the angles... Most likely buying them at Sparkfun, but not the 150$ compass, of course :wink:

Simon

// GPScam
// Created by Simon Madsen
// 06-10-2012
// dd-mm-yyyy
// Beer ware-licenced

// Compatible with hardware versions:
// 1.0

// Revision 1
// By Simon Madsen
//
// dd-mm-yyyy

#include <Servo.h>

float localLatitude = 0; // System latitude
float localLongtitude = 0; // System longtitude
float localAltitude = 0; // System altitude

float targetLatitude = 0; // Target latitude
float targetLongtitude = 0; // Target longitude
float targetAltitude = 0; // Target altitude

Servo panServo; // Servo used for panning
Servo tiltServo; // Servo used for tilting
int panServoPos = 0;
int tiltServoPos = 0;

float gyroInX = 0; // Xaxis data from the gyro
float gyroInY = 0; // Yaxis data from the gyro
float gyroInZ = 0; // Zaxis data from the gyro
float compassIn = 0; // Tilt-compensated heading data from the compass
float altimeterIn = 0; // Pressure data from the barometric pressure sensor

int XbeeSerial = 0;

void setup() {
panServo.attach(9);
tiltServo.attach(10);

Serial.begin(9600); // Communications with computer
Serial1.begin(115200); // Communications with Xbee

panServo.write(panServoPos);
tiltServo.write(tiltServoPos);

}

void loop() {
XbeeSerial = Serial1.read;
switch (XbeeSerial) {
case "1":
Serial.print("Remote Control");
panServo.write(Serial1.read);
Serial.print("panServo: "
Serial.print(Serial1.read);
delay(5);
tiltServo.write(Serial1.read);
Serial.print("tiltServo: "
Serial.print(Serial1.read);
break;

case "2":
delay(5);
targetLatitude = Serial1.read();
Serial.print(targetLatitude);
Serial.print();
delay(5);
targetLongtitude = Serial1.read();
Serial.print(targetLongtitude);
Serial.print();
delay(5);
targetAltitude = Serial1.read();
Serial.print(targetAltitude);
Serial.print();
break;
}
}

// This is where I cant choose between "switch case" or "if"

if (Serial.available()) {
if (Serial1.available()) {
if (Serial1.read = ("Remote Control")) {
panServo.write(Serial1.read);
delay(5);
tiltServo.write(Serial1.read);
}

if (Serial1.read = ("Target Location")) {
delay(5);
targetLatitude = Serial1.read();
Serial.print(targetLatitude);
Serial.print();
delay(5);
targetLongtitude = Serial1.read();
Serial.print(targetLongtitude);
Serial.print();
delay(5);
targetAltitude = Serial1.read();
Serial.print(targetAltitude);
Serial.print();
}
}
}
}

I can't decide whether to use "if"-sentences or "switch cases"... Do you have any suggestions?

simo9836:
I can't decide whether to use "if"-sentences or "switch cases"... Do you have any suggestions?

Switch cases are generally used when you would have "a lot of" if statements. I wouldn't use a switch case unless there would be more than 2 cases.

You handling of serial input looks distinctly dodgy. Serial.read() returns a byte, which will contain a character if that is what is being sent over the serial stream. If you receive a single character and want to see which character it is you need to compare it with a character constant '1', '2' etc not a string literal "1", "2" etc. If you want to receive a sequence of characters containing a string such as "Remote Control" then you need to read the characters one by one and store them in a buffer and then compare the contents of the buffer with your expected strings to see whether it matches any of them. To do the comparison, you'd need to use a function such as strcmp(), you can't simply use an == operator to compare string values.

      if (Serial1.read = ("Target Location")) {

There are at least two errors in this statement. As PeterH pointed out, the Serial.read() function, when called correctly, unlike here, returns a single byte. That single byte will never match a string, even if the correct operator was used, which is not the case here. Why are there parentheses around the literal string?

If you were to collect the data from the serial port into a NULL terminated array of chars, otherwise known as a string (which is not the same thing as a String - don't go there, either), you need to use strcmp() to compare the strings.

I think that, given the code you posted, this project is way over your head. Particularly as I see no evidence that there is a GPS anywhere in sight.