Skip to content

Conversation

@redn1nja
Copy link

This PR adds support for OPTICAL_FLOW_RAD MAVLink message according to #31588 into the AP_OpticalFlow_MAV driver

Copy link
Contributor

@peterbarker peterbarker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI must pass.

We also need an autotest for this - unfortunately we don't have a good example to swipe stuff from, but you would start with def OpticalFlow. Factor out the sanity checking function. Have a loop which sends in optical flow data corresponding to the vehicle's simulated velocity. Do the test at a speedup of 1. Let me know if this is a hill you won't be able to climb yet and I'll write something to get you going.

backend->handle_msg_rad(msg);
}
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#endif // AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED


#if AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED

void AP_OpticalFlow::handle_msg_rad(const mavlink_message_t &msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void AP_OpticalFlow::handle_msg_rad(const mavlink_message_t &msg)
void AP_OpticalFlow::handle_msg_optical_flow_rad(const mavlink_message_t &msg)

return;
}

if (backend != nullptr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (backend != nullptr) {
if (backend == nullptr) {
return;
}


if (backend != nullptr) {
backend->handle_msg_rad(msg);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}

(and fix indenting)

#if AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED
// handle optical flow rad mavlink messages
virtual void handle_msg_rad(const mavlink_message_t &msg) {}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#endif // AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED

Comment on lines 161 to 193


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines 143 to 147
// record time message was received
// TODO: dt between frames which is calculated in update state function
// is already stored in OPTICAL_FLOW_RAD message and can be taken from there
// instead of calculating it manually
latest_frame_us = AP_HAL::micros64();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the comment is correct here.

mavlink is not guaranteed delivery; assume that you will lose 90% of your packets and see how well things work in that case.

Comment on lines 158 to 160
// flow is already integrated so flow samples count will be equal to one
count = 1;
gyro_sum_count = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should aggregate received messages still - we're throwing away data otherwise.

However, this message is not dissimilar to the data handled on AP_OpticalFlow_HereFlow and it doesn't attempt to do that...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I can observe from MAVLink message documentation, each message contains information that allows to obtain average flow, and for OPTICAL_FLOW it is used for aggregation and manual integration later.

AP_OpticalFlow_HereFlow has almost the same type of message with the only difference in timestamp format, so maybe similar approach can be used here as well.
Same fact applies to previous comment regarding guarantees of delivery: if most packets are lost but each packet is self-sufficient, can we update using only one packet?

I suppose the better approach here could be to separate the OPTICAL_FLOW state and OPTICAL_FLOW_RAD state inside the driver and decide which one is used for update based on some criteria (e.g. quality field from the messages). Then we can leave the state handling of OPTICAL_FLOW as it is now and implement state handling similar to AP_OpticalFlow_HereFlow for OPTICAL_FLOW_RAD

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I can observe from MAVLink message documentation, each message contains information that allows to obtain average flow, and for OPTICAL_FLOW it is used for aggregation and manual integration later.

AP_OpticalFlow_HereFlow has almost the same type of message with the only difference in timestamp format, so maybe similar approach can be used here as well. Same fact applies to previous comment regarding guarantees of delivery: if most packets are lost but each packet is self-sufficient, can we update using only one packet?

I suppose the better approach here could be to separate the OPTICAL_FLOW state and OPTICAL_FLOW_RAD state inside the driver and decide which one is used for update based on some criteria (e.g. quality field from the messages). Then we can leave the state handling of OPTICAL_FLOW as it is now and implement state handling similar to AP_OpticalFlow_HereFlow for OPTICAL_FLOW_RAD

Given how different any aggregation is likely to be, separate states probably does make sense.

So from this message you now have a bunch of messages which you need to aggregate so you can present a flow rate to the system. Each message gives you data for an interval. We need to get an aggregate for the entire measurement interval since last we presented data to the system. That would appear to be finding flow rates for every message we receive and then stretching each of those messages so that we cover the entire measurement interval. And then summing and dividing by the message interval to get an aggregate rate.

That sounds a little difficult. We don't really need to do better than what we do with our existing message, so maybe just take the average of all of the samples we've received and don't bother weighting them as I just described... some support is better than no support, we can just add comments saying we can do better.

#endif
#if AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED
MSG_OPTICAL_FLOW_RAD = 101,
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif
#endif // AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED

#endif

#ifndef AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED
#define AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED 1
#define AP_MAVLINK_MSG_OPTICAL_FLOW_RAD_ENABLED (AP_OPTICALFLOW_ENABLED && HAL_PROGRAM_SIZE_LIMIT_KB > 2048)

@redn1nja redn1nja force-pushed the pr/optical_flow_rad_support branch from bafda30 to a8d8cd0 Compare December 1, 2025 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants