-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
AP_Camera: Add Camera Tracking functionality (WIP) #27773
base: master
Are you sure you want to change the base?
Conversation
} | ||
} | ||
|
||
void AP_Camera_Backend::handle_message_camera_information(mavlink_channel_t chan, const mavlink_message_t &msg) { |
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 think we will face conflicts when using a mavlink enabled camera (e.g. CAMx_TYPE = MavlinkCamV2) because we will also receive a camera_information message from these cameras.
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.
got it. now what will happen is if the message is coming from a camera, the camera's handle message will be called and if the message is from the tracking device it will forward it to base class's handle message.
Could you rebase this and also clarify what testing has been done? |
Could you create a separate PR with the python script in a new directory AP_Camera/examples? |
We should also consume the CAMERA_TRACKING_IMAGE_STATUS message and update the user |
import math | ||
from ultralytics import YOLO | ||
|
||
master = mavutil.mavlink_connection('127.0.0.1:14560') |
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.
we should allow the caller to specify the video source as an argument to the script.
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.
instructions on how to install would be good. E.g. what packages are required and how can they be installed? (e.g. pip)
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.
Do you need something like requirements.txt, i actually added a comment on top just for now.
# faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30)) | ||
faces= [final_list] | ||
if len(faces) == 0: | ||
# Do something if no faces were detected |
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.
We should be sending the CAMERA_TRACKING_IMAGE_STATUS message at regular intervals (1hz?) so that AP knows if we can't track the object any more
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.
We should support MAV_CMD_CAMERA_STOP_TRACKING
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.
Isnt that should be sent by the FC ? i.e.
CAMERA_TRACKING_IMAGE_STATUS
We should implement MAV_CMD_CAMERA_STOP_TRACKING |
center_x = (x + w) // 2 | ||
center_y = (y + h) // 2 | ||
cv2.circle(frame, (center_x, center_y), 3, (0, 255, 0), -1) | ||
#print("Center of the face: ({}, {})".format(center_x, center_y)) |
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.
instead of commented out lines, perhaps put a debug definition at the top to allow turning on/off debug
|
||
# gst-launch-1.0 -v udpsrc port=5600 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264' ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false | ||
|
||
gst_pipeline = ( |
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.
let's get a pipeline for at least the siyi camera gimbals using an ethernet connection to the companion computer
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 think we should move this definition to the top to make it easier to find and possibly we should try and create this pipe line based on arguments input by the caller
connection.wait_heartbeat() | ||
print("Heartbeat received from system (system %u component %u)" % (connection.target_system, connection.target_component)) | ||
# Send a heartbeat back to register the device | ||
connection.mav.heartbeat_send( |
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.
heartbeats must be sent regularly - at, say, 1Hz
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.
in a separate thread right ?
#print("Gimbal manager pitch and yaw angles message sent.") | ||
send_gimbal_manager_pitch_yaw_angles(0, 0, 0, 0, 0, 0, float("NaN"),float("NaN")) | ||
def send_command(): | ||
global centre_x, center_y |
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 looks odd
except: | ||
pass |
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 isn't acceptable in any Python script. You'd be surprised at how painful this can be.
Catch the exceptions you know about.
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.
needs exclusion in minimize include file and build options/extract features files added
|
||
# Start listening for MAVLink messages | ||
while True: | ||
msg = connection.recv_match(type='COMMAND_LONG', blocking=True) |
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 the call need to be blocking here?
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.
Dont you think it should be ?
"rtph264depay ! h264parse ! queue ! avdec_h264 ! videoconvert ! appsink" | ||
) | ||
|
||
cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER) |
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.
The default versions of opencv-python
and opencv-contrib-python
do not have gstreamer support enabled. A custom build of the Python packages from source is required for this (at least this is the case on macOS). To reduce the complexity it may be easier to use the gstreamer Python bindings to capture the video stream and then make this available to opencv. The BlueROV docs have a guide for this: https://www.ardusub.com/developers/opencv.html.
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.
Yes you're right.
# Main function | ||
def main(): | ||
# Send camera information message | ||
send_camera_information(connection) |
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.
There seems to be two ways to ensure that the MAV_CMD_CAMERA_TRACK_POINT
response expected below is triggered when sending the camera info. One is in AP_Camera::handle_command(const mavlink_command_int_t &packet)
and requires a MAV_CMD_CAMERA_TRACK_POINT
message be sent. The other is to use an aux switch to enable camera image tracking. This is the setup I used for testing.
RC13_OPTION 174.0 # Camera Image Tracking
Along with
param set CAM1_TRK_ENABLE 1
param set CAM1_TRK_SYSID 245
param set CAM1_TRK_COMPID 0
then run the script, enable tracking with
MANUAL> rc 13 1900
and check the output.
Either way all of this needs to be documented.
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.
That is a good way actually, the thing is RC switch based tracking will tell only to start tracking anything in the frame. atlast we need to send the CAMERA_TRACKING messages to work with specific objects
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.
@rmackay9 @peterbarker @srmainwaring Have a look
connection.wait_heartbeat() | ||
print("Heartbeat received from system (system %u component %u)" % (connection.target_system, connection.target_component)) | ||
# Send a heartbeat back to register the device | ||
connection.mav.heartbeat_send( |
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.
in a separate thread right ?
import math | ||
from ultralytics import YOLO | ||
|
||
master = mavutil.mavlink_connection('127.0.0.1:14560') |
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.
Do you need something like requirements.txt, i actually added a comment on top just for now.
"rtph264depay ! h264parse ! queue ! avdec_h264 ! videoconvert ! appsink" | ||
) | ||
|
||
cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER) |
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.
Yes you're right.
# faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30)) | ||
faces= [final_list] | ||
if len(faces) == 0: | ||
# Do something if no faces were detected |
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.
Isnt that should be sent by the FC ? i.e.
CAMERA_TRACKING_IMAGE_STATUS
@khanasif786, thanks for all your efforts on this. Could you rebase this on master too? Let's also make it "ready for review" instead of "WIP" |
8c94c12
to
7dd51ed
Compare
7dd51ed
to
766f08a
Compare
|
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.
still needs the changes I requested
const uint8_t fw_ver_build = (camera_settings._cam_info.firmware_version & 0xFF000000) >> 24; | ||
|
||
// display camera info to user | ||
gcs().send_text(MAV_SEVERITY_INFO, "Camera: %s.32 %s.32 fw:%u.%u.%u.%u", |
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 should be %.32s
instead, probably carried over from the code before #27562
} | ||
|
||
_link->send_message(MAVLINK_MSG_ID_COMMAND_LONG, (const char*)&pkt); | ||
GCS_SEND_TEXT(MAV_SEVERITY_WARNING,"sent message to device sysid %d and comp %d",tracking_device_sysid,tracking_device_compid); |
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 could be removed (or should be MAV_SEVERITY_INFO
) , and the sysid
, compid
info added to the Tracking: New Tracking request
message on L28
@khanasif786, I think perhaps the follow-functionality should be split into a separate PR, with this one focussing on the core camera tracking changes. The addition of I've written a MAVProxy module ( It's working in simulation, still having a few issues setting up correct sys_id and component_id for all components on hardware (CubeOrangePlus with RPi4 companion). AFAICT the RPi4 copes with the The MAVProxy code is here: https://github.com/srmainwaring/MAVProxy/tree/wips/wip-camera-tracking. It is a WIP with a lot of debug message code included that will eventually be pruned. Let me know if you'd like a walk through. A rebase of this PR on master here: https://github.com/srmainwaring/ardupilot/tree/mav_cmd_camera_final_rebased. I'd force push, but don't have access. There are a few conflicts resolved. |
break; | ||
} | ||
|
||
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"Tracking: New Tracking request"); |
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.
Message prefix should be consistent: AP_Camera:
is used elsewhere.
Perhaps add sysid
, compid
here as this is useful information when setting up the system, and if they are not correct the function returns early (so the message including them below is not reported).
enum CAMERA_TRACKING_STATUS_FLAGS : uint8_t { | ||
CAMERA_TRACKING_STATUS_FLAGS_IDLE, | ||
CAMERA_TRACKING_STATUS_FLAGS_ACTIVE, | ||
CAMERA_TRACKING_STATUS_FLAGS_ERROR | ||
}; |
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.
Shadows
#define HAVE_ENUM_CAMERA_TRACKING_STATUS_FLAGS
typedef enum CAMERA_TRACKING_STATUS_FLAGS
{
CAMERA_TRACKING_STATUS_FLAGS_IDLE=0, /* Camera is not tracking | */
CAMERA_TRACKING_STATUS_FLAGS_ACTIVE=1, /* Camera is tracking | */
CAMERA_TRACKING_STATUS_FLAGS_ERROR=2, /* Camera tracking in error state | */
CAMERA_TRACKING_STATUS_FLAGS_ENUM_END=3, /* | */
} CAMERA_TRACKING_STATUS_FLAGS;
#endif
in mavlink/v2.0/common/common.h
handle_message_camera_information(chan,msg); | ||
break; | ||
case MAVLINK_MSG_ID_CAMERA_TRACKING_IMAGE_STATUS: | ||
handle_message_camera_tracking_image_status(chan,msg); |
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.
Missing break
. Compilation with clang
fails.
@@ -86,6 +86,14 @@ class AP_Camera_Backend | |||
// p1,p2 are in range 0 to 1. 0 is left or top, 1 is right or bottom | |||
bool set_tracking(TrackingType tracking_type, const Vector2f& top_left, const Vector2f& bottom_right); | |||
|
|||
// returns true if the objkect to be tracked is visible in the frame |
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.
sp. objkect -> object
This adds support for a companion computer to perform image tracking using any of the backends