-
-
Notifications
You must be signed in to change notification settings - Fork 504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
offboard: automatically send setpoins at set rate #134
Conversation
plugins/offboard/offboard_impl.cpp
Outdated
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this return here so that the following code isn't executed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good catch, thank you!
Looks awesome. Some thoughts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added some feedback. Will leave for @shakthi-prashanth-m to do technical C++ review.
@julianoes As part of this can I please also get a small docs update. For all the members in
to
etc.And also, in particular can I also get a closing ")" on these two:
|
@@ -76,12 +78,9 @@ bool offb_ctrl_ned(Device &device) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@julianoes In line above, why sleep for one second after starting offboard? API should not require artificial timing breaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
@@ -76,12 +78,9 @@ bool offb_ctrl_ned(Device &device) | |||
|
|||
// Let yaw settle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think we need this note - since we show it as log in next line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
@@ -76,12 +78,9 @@ bool offb_ctrl_ned(Device &device) | |||
|
|||
// Let yaw settle. | |||
offboard_log(offb_mode, " Let yaw settle..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This log is confusing - because at this point we haven't told the user we're yawing. We also report done, which I think is redundant since we're not actually checking that we're done and we then say the next step.
Suggest replace with following text - states that we're yawing and gives user 3 seconds to watch that behaviour. We don't need to tell the watcher that yaw is settling, but we add a comment so programmers know why we added that sleep.
offboard_log(offb_mode, " Turn (yaw) clockwise to face East (90 deg.)");
device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 90.0f});
sleep_for(seconds(3)); // Let yaw settle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense
@@ -99,31 +98,24 @@ bool offb_ctrl_ned(Device &device) | |||
// NOTE: Use sleep_for() after each velocity-ned command to closely monitor their behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Section above is confusing to watch and the code is a bit complicated:
- Description incorrect
- The vehicle does not "go right". It turns to face east unless it is already facing east.
- It technically does "oscillate", but that could mean almost anything.
- Propose change text to "Oscillate along a North-South path. Turn clockwise to face East (90 deg.)"
- Propose make this do two cycles to be easier to observe when running the example (ie.
const unsigned steps = (unsigned)(one_cycle / step_size);
toconst unsigned steps = 2 * (unsigned)(one_cycle / step_size);
- Maybe "Done" is OK here because the action is quite extended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, changed it along these lines.
@@ -99,31 +98,24 @@ bool offb_ctrl_ned(Device &device) | |||
// NOTE: Use sleep_for() after each velocity-ned command to closely monitor their behaviour. | |||
|
|||
offboard_log(offb_mode, " Turn clock-wise 270 deg"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Turn clockwise to face West (270 deg.)"
} | ||
device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 270.0f}); | ||
sleep_for(seconds(2)); | ||
|
||
offboard_log(offb_mode, " Done"); | ||
|
||
offboard_log(offb_mode, " Go UP 2 m/s, Turn clock-wise 180 deg"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Go UP 2 m/s. Turn clockwise to face South (180 deg.)"
} | ||
device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 270.0f}); | ||
sleep_for(seconds(2)); | ||
|
||
offboard_log(offb_mode, " Done"); | ||
|
||
offboard_log(offb_mode, " Go UP 2 m/s, Turn clock-wise 180 deg"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@julianoes When this command executes the vehicle should turn clockwise from 270 through to 0 and back round to 180 - because the yaw value is positive. What I'm seeing in SITL is that it goes anticlockwise back to 180 irrespective of the sign on the yaw value. So either a bug in our docs, or dronecore or PX4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just goes the quickest way to the new setpoint. I'll get rid of the "(anti-)clock-wise" indications.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_ned({0.0f, 0.0f, -2.0f, 180.0f}); | ||
sleep_for(seconds(4)); | ||
offboard_log(offb_mode, " Done..."); | ||
|
||
offboard_log(offb_mode, " Turn clock-wise 90 deg"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turn clockwise to face East (90 deg.)"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would also be good if at least one of these cases turned anticlockwise to demonstrate that working. Certainly we need that in the test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said, it's up to the controller. We can only really check it for body coordinates where we control yaw rate.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_ned({0.0f, 0.0f, 0.0f, 90.0f}); | ||
sleep_for(seconds(4)); | ||
offboard_log(offb_mode, " Done..."); | ||
|
||
offboard_log(offb_mode, " Go DOWN 1.0 m/s"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go DOWN 1.0 m. Turn clockwise to face North (0 deg.)
@@ -152,53 +144,39 @@ bool offb_ctrl_body(Device &device) | |||
|
|||
// Turn around yaw and climb | |||
offboard_log(offb_mode, " Turn around yaw & climb"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Text should be: " Go UP 1 m/s. Turn clockwise at 60 degrees/second."
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, -1.0f, 60.0f}); | ||
sleep_for(seconds(2)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't all these cases print "Done" for consistency? Either all should do or all should not do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed all.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, -1.0f, 60.0f}); | ||
sleep_for(seconds(2)); | ||
|
||
// Turn back | ||
offboard_log(offb_mode, " Turn back"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" Turn the other direction (anticlockwise) at 60 degrees/second."
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, -1.0f, 60.0f}); | ||
sleep_for(seconds(2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe sleep 5 seconds - so this is easy to observe for someone viewing the example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, -60.0f}); | ||
sleep_for(seconds(2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe sleep 5 seconds - so this is easy to observe for someone viewing the example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f}); | ||
sleep_for(seconds(2)); | ||
// NOTE: Use sleep_for() after each velocity-ned command to closely monitor their behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate Note. If this is to stay, make sure it changes to "after velocity-body".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
device.offboard().set_velocity_body({5.0f, 0.0f, 0.0f, 60.0f}); | ||
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({5.0f, 0.0f, 0.0f, 60.0f}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propose rotate at 30.0f (bigger circle) and wait for 15 seconds. This is much more visible in QGC., and it doesn't hurt to show different rates at work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
sleep_for(milliseconds(10)); | ||
} | ||
device.offboard().set_velocity_body({0.0f, 0.0f, 0.0f, 0.0f}); | ||
sleep_for(seconds(5)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to at least 8 seconds.
The script would keep on sending setpoints but not try to enter offboard mode again. I guess we could check if we're still in the correct mode and complain otherwise. The problem is though that the setter does not return with an error. What about having a function to check if offboard is still running?
Thanks, I copied what you suggested.
Maybe on a really slow link. We could default to 10 Hz which should work for all cases I can think of.
The benefit of having |
Sure, done. |
2c066b6
to
db67ed5
Compare
plugins/offboard/offboard_impl.cpp
Outdated
// reschedule the next call, so we don't send setpoints too often. | ||
_parent->reset_call_every(_call_every_cookie); | ||
} | ||
_velocity_ned_yaw = velocity_ned_yaw; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we assign this before entering calling send_velocity_ned()
at line:191.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spotting! Call every will only schedule it and not run it immediately, however, it is still a race, so you're right!
Changed in 2c0a887.
plugins/offboard/offboard_impl.cpp
Outdated
// reschedule the next call, so we don't send setpoints too often. | ||
_parent->reset_call_every(_call_every_cookie); | ||
} | ||
_velocity_body_yawspeed = velocity_body_yawspeed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this happen before Line 218 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, same thing.
@@ -164,17 +247,19 @@ void OffboardImpl::set_velocity_ned(Offboard::VelocityNEDYaw velocity_ned_yaw) | |||
//const static uint16_t IGNORE_YAW = (1 << 10); | |||
const static uint16_t IGNORE_YAW_RATE = (1 << 11); | |||
|
|||
const float yaw = to_rad_from_deg(velocity_ned_yaw.yaw_deg); | |||
_mutex.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this lock makes sure _velocity_body_ned_yaw
has updated value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I guess the lock prevents the race from happening. Still changed it makes more sense.
This adds a class to call a callback et a constant rate (constant interval). Presumably, this should be done using some sort of proper event loop but this could be good enough for now.
This means that we can reschedule the next time call_every is triggered, so the interval time is reset.
This changes the offboard API so that it is no longer required to send setpoints at least every 0.5 seconds. Instead, this enables to set a setpoint once and only set it again when it changes. The implementation will automatically send it at 20 Hz internally. If the setpoints need to be sent at a higher rate, e.g. for very smooth control, that is still possible by just setting the setpoints at high rate. Whenever a setpoint changes, it is immediately sent to the vehicle.
The new API does not require the setpoint to be constantly set.
We don't need to check whether a command times out because that is reliably handled inside device_impl.
This adds an interface to check if offboard is still active which means the vehicle is still in offboard mode and offboard setpoints are still sent. If the vehicle drops out of offboard mode, we stop sending setpoints and it is required to re-initiate sending offboard commands.
This prevents a race between the first time `send_velocity_` is called and setting the cached setpoint that it will send.
db67ed5
to
2c0a887
Compare
Added, thx.
Note yet, but it makes sense to add a check for it and stop sending setpoints... done in a9c83ec. |
We could merge this for now. I'll figure out the CI issues in a separate pull request. The problem is that timing sensitive tests fail on slow or busted CI instances. The solution will be to mock time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me!
CI troubles addressed in #147. |
This changes the offboard API so that it is no longer required to send
setpoints at least every 0.5 seconds. Instead, this enables to set a
setpoint once and only set it again when it changes. The implementation
will automatically send it at 20 Hz internally.
If the setpoints need to be sent at a higher rate, e.g. for very smooth
control, that is still possible by just setting the setpoints at high
rate. Whenever a setpoint changes, it is immediately sent to the
vehicle.
Tested in SITL using the integration tests as well as the offboard example.