Incorporating GPS into my project

Hi All,

I am looking to incorporate GPS into a Panoramic Photography robot project, the GPS would have two functions, the first would be to stamp a file with the location of the image (which would be stored in an XML file), and also to store the Time the panorama was started, and the time each photo was taken.

My issue is how to achieve this when I call long running functions, I can code in a wait to get a GPS fix before the function is called, it would then store the latitude and longitude as variables which get put into the XML file, but once the panorama function is called, it could end up taking up to thousands of photos running for potentially hours.

The project does this by working out the x and y axis degrees to travel, the field of view of the lens, and then the number of photos needed across each axis, running through an x and y loop like below;

  for(byte y = 0; y < Stepsy; y++){
    servoy.write(y * grados_verticales + Starty);

    for(byte x = 0; x < Stepsx; x++){
     servox.write((Stepsx-x) * grados_horizontales + Startx);
        progress = progress + 1;
      delay(750); //stabilization delay
      //take photo
      delay(250); //camera buffer delay
    }
  }

So i had thought to use TinyGPS++ which is the best thing I think to achieve what I need, which has a fairly simple ‘update GPS’ style feature, is the best way to do this to create a void sub / function which I call say after the progress = progress + 1; which updates the GPS if data is available, then I can extract the timestamp variable from TinyGPS++ near the //takephoto comment.

I should clarify, In the main loop I ‘wait’ for serial commends for the robot to determine what to do, so I can put this in the loop and wait until GPS is updated before it can start doing an issued command, and use the Latitude / Longitude in the XML, my issue is more around updating the TimeStamp for each photo, and what the most efficient way to do that is when there are long-running loops.

Many thanks!

while (ss.available() > 0)
  gps.encode(ss.read());

What do you mean, "long running loops"? If you mean a loop() function that takes a long time to run, then you have a bad design and have to go back the the drawing board.

Sorry, I mean that a sub-routine is called which handles taking the photos and movement etc which may take hours since the sub-routine loops a heap of times moving the position, taking a photo, moving the position taking a photo and so on, not so much the loop takes ages to complete once, but it may have to do an inner loop over thousands of times moving across the x and y axis.

The reason I had moved it to a sub, was effectively that in the main loop I handle capturing user input e.g. where to start and finish, the focal length of the camera and so on, but also other commands like move to position x,y, take a test capture, take a 360 spherical panorama but once the command is issued the unit essentially goes about doing that task through the respective subs.

In between telling the camera to take pictures and store the data, you need to be doing other things, like checking whether the GPS has characters to process or an updated position, read out the current time, etc. The main loop should never be waiting for anything.

Thanks for that, so sounds like calling an internal sub in-between doing things (e.g. moving camera, taking pictures) might be the easiest way to go.

Okay. Whatever an internal sub is.

Sorry, I meant calling another subroutine

TravisH:
Sorry, I meant calling another subroutine

How many times a second will your loop() function execute?

So the main loop function will loop fairly quickly at the start, it will just be checking to see if new serial data is available and then processing that data if it arrives to either update GPS information, or to determine if it needs to call a specific subroutine (e.g. take a 360 pano, or take a gigapixel style image).

Once the specific subroutine is called, that is the bit that may take a bit of time, in reality the 360 pano takes about 6 * 60 degree photos moving various angles, then takes a photo of the sky for the top, that process is likely to take about 1 minute.

The longer bit is if a gigapixel image is taken, this may require hundreds of images across the X axis, then a significant number across the Y axis, it is not uncommon depending on the lens focal length being used to take x = 100, y = 20 for example, using that example, of say 2000 images, and allowing about 1.5 seconds per image it would take about 3000 seconds to take that number of images.

Using that example though, there are a lot of loops within the sub, so although it would take 3000 seconds each loop would be as I said say around 1-1.5 seconds, so I do have time within that to check GPS serial, and Bluetooth serial and the likes (e.g. for STOP commands).

Once the unit is started, it just needs to go about its job; I don't need to read sensor data just check bluetooth and GPS every now and again, but there would be no major interaction, i.e. it does 1 job at a time, no queues :), I just have to wait until it is finished or I stop it.

If you do not run GPS concurrently, you will have to wait for the next NMEA decode to come around, to get the data. If you can live with that delay, then fine.

But a robot that can only do one thing at a time is rather a limited one. Sooner or later, you will have to bite the bullet and learn to implement concurrency.