3

I'm trying to send a drone a new set of coordinates every 1/2 of a second. Right now, it's not working the way I planned on it working (aka it's not working at all). I have 90 different Lat, Long, and Alt coordinates all predetermined inside my .js file. They are listed like this-

setTimeout(function () {long_in=-74.61122515230907;lat_in=41.05861743700108;alt_in=10}, 5000);
setTimeout(function () {long_in=-74.61124258212661;lat_in=41.05864962647036;alt_in=10}, 10000);
setTimeout(function () {long_in=-74.61125021662482;lat_in=41.05867214783328;alt_in=10}, 15000);

and so on...

Then they will need to pass thru this function -

if (coordinate == "GPS") {
    console.log("GPS go");
    lat_out = lat_in;
    long_out = long_in;
    alt_out = alt_in;
    console.log(lat_out, long_out, alt_out)
}

And finally it will send this command to the drone-

var msgdata = {};
msgdata["twist"] = {};
msgdata.twist["twist"] = {};
msgdata.twist.twist["linear"] = {};
msgdata.twist.twist.linear["x"] = lat_out;
msgdata.twist.twist.linear["y"] = long_out;
msgdata.twist.twist.linear["z"] = alt_out;
msgdata.twist.twist["angular"] = {};
msgdata.twist.twist.angular["z"] = 1.00;
msgdata["tolerance"] = 2.00;
msgdata["async"] = true;
msgdata["relative"] = false;
msgdata["yaw_valid"] = true;
msgdata["body_frame"] = false;

$.ajax({
    type: "POST",
    dataType: "json",
    data: JSON.stringify(msgdata),
    url: "http://" + ip + "/ros/" + namespace + "/navigation/position_set",
    success: function (data) {
        console.log(data, "Coordinates sent", lat_out,long_out,alt_out);
    }
});

I have defined all of my variables prior to this code globally. All of the commands work perfectly fine, I just can't get them to all refresh every 1/2 of a second. Do I need to have all of these commands inside every setTimeout or something? Thanks for the help.

Kyle Foley
  • 190
  • 7
  • 1
    setTimeout is not guarenteed to run un exactly x amount of time. The actual time of execution can and will vary depending on what else is happening. Remember JS is ([kinda](http://stackoverflow.com/a/2734311/542251)) single threaded – Liam Aug 11 '16 at 12:04
  • The timing doesn't really need to be precise for this code, the issue is refreshing the function – Kyle Foley Aug 11 '16 at 12:07
  • If you want them to be run sequencly you'd be better using a callback that then set a timeout of a static amount. I know you said it doesn't need to be precise, but surely that's not true if your controlling a drone? The exact sequence may not be preserved so rather than a->b->c it could run a->c->b. Then your in a totally differnt location to where you thought you were – Liam Aug 11 '16 at 12:10
  • Ok yeah, I do see where you're coming from with this. Think it might be better to do a `setInterval`? – Kyle Foley Aug 11 '16 at 12:16
  • 1
    No, what he means is to use a callback chain to assure each request start after say `5000ms` after the previous operation is completed. So even if this `5000ms` isn't exactly precise, you can be guaranteed the order is preserved. – Iceman Aug 11 '16 at 12:18
  • I have written an answer below using callbacks. have a look. – Iceman Aug 11 '16 at 12:22
  • Got it, that makes sense. Thanks for the help guys – Kyle Foley Aug 11 '16 at 12:22

2 Answers2

2

You have to run recalculation inside setTimeout after you set a value.

Andrei Zhytkevich
  • 8,039
  • 2
  • 31
  • 45
2

Yes you need to make the call again and again. You could wrap it in a function and make the call happen again and again from the setTimeout.

I have created a callback chain to guarantee order of execution based on @Liam's recommendation and the comments discussion.

setTimeout(function() {
  long_in = -74.61122515230907;
  lat_in = 41.05861743700108;
  alt_in = 10;
  prepSignal(long_in, lat_in, alt_in, function() {
    setTimeout(function() {
      long_in = -74.61124258212661;
      lat_in = 41.05864962647036;
      alt_in = 10;
      prepSignal(long_in, lat_in, alt_in, function() {
        setTimeout(function() {
          long_in = -74.61125021662482;
          lat_in = 41.05867214783328;
          alt_in = 10;
          prepSignal(long_in, lat_in, alt_in);
        }, 5000);
      });
    }, 5000);
  });
}, 5000);


var coordinate = "GPS";

function prepSignal(long_in, lat_in, alt_in, callback) {
  if (coordinate == "GPS") {
    console.log("GPS go");
    lat_out = lat_in;
    long_out = long_in;
    alt_out = alt_in;
    console.log(lat_out, long_out, alt_out, callback);
    sendSignal(long_in, lat_in, alt_in, callback);

  }

  function sendSignal(long_in, lat_in, alt_in, cb) {
    var msgdata = {};
    msgdata["twist"] = {};
    msgdata.twist["twist"] = {};
    msgdata.twist.twist["linear"] = {};
    msgdata.twist.twist.linear["x"] = lat_out;
    msgdata.twist.twist.linear["y"] = long_out;
    msgdata.twist.twist.linear["z"] = alt_out;
    msgdata.twist.twist["angular"] = {};
    msgdata.twist.twist.angular["z"] = 1.00;
    msgdata["tolerance"] = 2.00;
    msgdata["async"] = true;
    msgdata["relative"] = false;
    msgdata["yaw_valid"] = true;
    msgdata["body_frame"] = false;

    $.ajax({
      type: "POST",
      dataType: "json",
      data: JSON.stringify(msgdata),
      url: "http://" + ip + "/ros/" + namespace + "/navigation/position_set",
      success: function(data) {
        console.log(data, "Coordinates sent", lat_out, long_out, alt_out);
      if(cb && typeof cb == "function") {
          cb();
      }

      }
    });
  }
}
Iceman
  • 6,035
  • 2
  • 23
  • 34