mavlink / MAVSDK

API and library for MAVLink compatible systems written in C++17
https://mavsdk.mavlink.io
BSD 3-Clause "New" or "Revised" License
633 stars 509 forks source link

Camera Commands Infinite loop with gazebo sitl with typhoon model #2431

Open dsurver opened 3 weeks ago

dsurver commented 3 weeks ago

Hi, I am trying to run the camera+gimbal with the gazebo sitl (px4 1.15.0) with mavsdk-python (mavsdk 2.12.11). When I run the camera.py example while manually running the mavsdk_server, I get the following logs from mavsdk_server. On the Mavsdk-python side i get timeout messages. The gimbal.py example runs fine without any problem.

Does this mean that the SITL with Typhoon model does not have camera server side implementation? Or am i missing something. I would like to test as much camera plugin with sitl mode as possible. Are there any alternatives for this? Thanks!

[10:30:48|Info ] MAVSDK version: v2.12.11 (mavsdk_impl.cpp:26)
[10:30:48|Debug] Command debugging is on. (mavlink_command_receiver.cpp:26)
[10:30:48|Info ] New system on: 127.0.0.1:54247 (with system ID: 1) (udp_connection.cpp:178)
[10:30:48|Debug] New system ID: 1 Comp ID: 1 (mavsdk_impl.cpp:750)
[10:30:48|Debug] Command debugging is on. (mavlink_command_sender.cpp:15)
[10:30:48|Debug] Component Autopilot (1) added. (system_impl.cpp:366)
[10:30:48|Debug] Component Gimbal (154) added. (system_impl.cpp:366)
[10:30:48|Info ] System discovered (connection_initiator.h:39)
[10:30:48|Info ] Server started (grpc_server.cpp:169)
[10:30:48|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:170)
[10:30:49|Warn ] Vehicle type changed (new type: 13, old type: 0) (system_impl.cpp:217)
[10:30:49|Debug] Discovered 2 component(s) (system_impl.cpp:509)
[10:30:49|Debug] COMMAND_LONG 520 to send to 1, 1 (mavlink_command_sender.cpp:112)
[10:30:49|Debug] MAVLink: info: Connection to ground station lost        (system_impl.cpp:243)
[10:30:49|Debug] Sent command 520 (mavlink_command_sender.cpp:407)
[10:30:49|Debug] Received command ack for 520 with result 0 after 0.00235067 s (mavlink_command_sender.cpp:185)
[10:30:49|Debug] MAVLink: critical: Preflight Fail: vertical velocity unstable (system_impl.cpp:243)
[10:30:49|Debug] MAVLink: info: GCS connection regained  (system_impl.cpp:243)
[10:30:49|Debug] MAVLink: critical: Preflight Fail: vertical velocity unstable (system_impl.cpp:243)
[10:31:41|Debug] MAVLink: critical: Preflight Fail: height estimate not stable (system_impl.cpp:243)
[10:31:50|Error] notify_current_settings has no camera definition (camera_impl.cpp:2149)
[10:31:50|Error] notify_possible_setting_options has no camera definition (camera_impl.cpp:2192)
[10:31:50|Debug] COMMAND_LONG 522 to send to 1, 100 (mavlink_command_sender.cpp:112)
[10:31:50|Debug] Sent command 522 (mavlink_command_sender.cpp:407)
[10:31:50|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.001559 s (mavlink_command_sender.cpp:172)
[10:31:50|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:50|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:50|Warn ] sending again after 0.508127 s, retries to do: 3  (522). (mavlink_command_sender.cpp:320)
[10:31:50|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.511235 s (mavlink_command_sender.cpp:172)
[10:31:50|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:51|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:51|Warn ] sending again after 1.00886 s, retries to do: 2  (522). (mavlink_command_sender.cpp:320)
[10:31:51|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 1.01229 s (mavlink_command_sender.cpp:172)
[10:31:51|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:51|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:51|Warn ] sending again after 1.51331 s, retries to do: 1  (522). (mavlink_command_sender.cpp:320)
[10:31:51|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 1.51555 s (mavlink_command_sender.cpp:172)
[10:31:51|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:52|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:52|Error] Retrying failed (522) (mavlink_command_sender.cpp:346)
[10:31:55|Debug] COMMAND_LONG 522 to send to 1, 100 (mavlink_command_sender.cpp:112)
[10:31:55|Debug] Sent command 522 (mavlink_command_sender.cpp:407)
[10:31:55|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.00203983 s (mavlink_command_sender.cpp:172)
[10:31:55|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:55|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:55|Warn ] sending again after 0.510594 s, retries to do: 3  (522). (mavlink_command_sender.cpp:320)
[10:31:55|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.512605 s (mavlink_command_sender.cpp:172)
[10:31:55|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:56|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:56|Warn ] sending again after 1.01595 s, retries to do: 2  (522). (mavlink_command_sender.cpp:320)
[10:31:56|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 1.02022 s (mavlink_command_sender.cpp:172)
[10:31:56|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:56|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:56|Warn ] sending again after 1.51854 s, retries to do: 1  (522). (mavlink_command_sender.cpp:320)
[10:31:56|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 1.52286 s (mavlink_command_sender.cpp:172)
[10:31:56|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:31:57|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:31:57|Error] Retrying failed (522) (mavlink_command_sender.cpp:346)
[10:32:00|Debug] COMMAND_LONG 522 to send to 1, 100 (mavlink_command_sender.cpp:112)
[10:32:00|Debug] Sent command 522 (mavlink_command_sender.cpp:407)
[10:32:00|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.00317863 s (mavlink_command_sender.cpp:172)
[10:32:00|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:32:00|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:32:00|Warn ] sending again after 0.500759 s, retries to do: 3  (522). (mavlink_command_sender.cpp:320)
[10:32:00|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.504278 s (mavlink_command_sender.cpp:172)
[10:32:00|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[10:32:01|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[10:32:01|Warn ] sending again after 1.01029 s, retries to do: 2  (522). (mavlink_command_sender.cpp:320)
JonasVautherin commented 3 weeks ago

Does this mean that the SITL with Typhoon model does not have camera server side implementation?

I believe this is correct. At least I know that https://github.com/JonasVautherin/px4-gazebo-headless does not have a camera implementation :+1:.

dsurver commented 2 weeks ago

Ah, then I know why it does not work. But why does the server go into an infinite loop?

Does this line mean something to debug this problem? Is 1/100 sysid/comp id for the supposed camera component?

Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100)

The command should just fail right?

dsurver commented 2 weeks ago

Also, the typhoon_480 model used in https://github.com/JonasVautherin/px4-gazebo-headless does have a camera_manager_plugin attached to it, so why does it not work with mavsdk_server commands?

CameraManager Typhoon_480

JonasVautherin commented 2 weeks ago

Is 1/100 sysid/comp id for the supposed camera component?

I think so, yes.

The command should just fail right?

If it was sent to 1/100, then 1/1 should not ACK it. If there is no camera server, it should time out.

Also, the typhoon_480 model used in https://github.com/JonasVautherin/px4-gazebo-headless does have a camera_manager_plugin attached to it

I never enabled it in px4-gazebo-headless, because I don't think it existed when I wrote it and I never used the camera_manager_plugin myself. If you know how to use it and manage to enable it in px4-gazebo-headless, I would love to get a PR!

dsurver commented 2 weeks ago

I am not sure if I know how to adapt it. I will try to explain what I learned. I guess the Gazebo Model file Typhoon SDF Jinja defines the plugins attached to the model. And in this model it is already containing the camera_manager_plugin as well as gimbal_controller.

Then there is a init script PX4 Init Script SITL contains the command which starts mavlink streaming for the camera module as well as gimbal.

Then there is another override file i think which defines additional commands such as default params as for Typhoon 480 which defines some parameters for the gimbal (MNT_MODE_IN, MNT_MODE_OUT which both means Mavlink 2 Gimbal). I do not see any param for camera and also could not successfully find in the px4 documentation which param to set for camera. Do you have any hint?

dsurver commented 2 weeks ago

just checked the sdf file generated in the gazebo px4 headless docker container and the camera manager related parameters are:

<plugin name="CameraManagerPlugin" filename="libgazebo_camera_manager_plugin.so">
            <robotNamespace>typhoon_h480</robotNamespace>
            <interval>1</interval>
            <width>3840</width>
            <height>2160</height>
            <maximum_zoom>8.0</maximum_zoom>
            <video_uri>udp://127.0.0.1:5600</video_uri>
            <system_id>1</system_id>
            <cam_component_id>100</cam_component_id>
            <mavlink_cam_udp_port>14530</mavlink_cam_udp_port>
        </plugin>

so at least the

Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100)

somehow makes sense since the camera component has id 100. Does the udp port needs to be modified? At least the video stream works so there has to be something wrong with mavlink configuration somewhere.

There was another user with similar problem last year.

dsurver commented 2 weeks ago

the simulator logs throws an error related to exiftool sh: 1: exiftool: not found

and then proceeds to log the following:

INFO  [dataman] data manager file './dataman' size is 7872608 bytes
INFO  [init] PX4_SIM_HOSTNAME: localhost
INFO  [simulator_mavlink] Waiting for simulator to accept connection on TCP port 4560
INFO  [simulator_mavlink] Simulator connected on TCP port 4560.
INFO  [lockstep_scheduler] setting initial absolute time to 340000 us
WARN  [vehicle_angular_velocity] no gyro selected, using sensor_gyro_fifo:0 1310988
INFO  [commander] LED: open /dev/led0 failed (22)
ERROR [param] Parameter UXRCE_DDS_DOM_ID not found.
etc/init.d-posix/rcS: 310: etc/init.d-posix/rcS: uxrce_dds_client: not found
INFO  [mavlink] mode: Normal, data rate: 4000000 B/s on udp port 18570 remote port 14550
INFO  [mavlink] mode: Onboard, data rate: 4000000 B/s on udp port 14580 remote port 14540
INFO  [mavlink] mode: Onboard, data rate: 4000 B/s on udp port 14280 remote port 14030
INFO  [mavlink] mode: Gimbal, data rate: 400000 B/s on udp port 13030 remote port 13280
INFO  [mavlink] mode: Onboard, data rate: 4000 B/s on udp port 14558 remote port 14530
INFO  [logger] logger started (mode=all)
INFO  [logger] Start file log (type: full)
INFO  [logger] [logger] ./log/2024-10-23/16_14_49.ulg
INFO  [logger] Opened full log file: ./log/2024-10-23/16_14_49.ulg
INFO  [mavlink] MAVLink only on localhost (set param MAV_{i}_BROADCAST = 1 to enable network)
INFO  [mavlink] MAVLink only on localhost (set param MAV_{i}_BROADCAST = 1 to enable network)
INFO  [px4] Startup script returned successfully
pxh> INFO  [mavlink] partner IP: 127.0.0.1
INFO  [tone_alarm] home set
INFO  [commander] Ready for takeoff!

says nothing about camera. probably failing to load the camera driver because exiftool not found?

dsurver commented 2 weeks ago

aha, just found this error message in the camera plugin:

camera plugin error message

if (system("exiftool -ver &>/dev/null") != 0) {
        gzerr << "exiftool not found. geotagging_images plugin will be disabled" << endl;
        gzerr << "On Ubuntu, use 'sudo apt-get install libimage-exiftool-perl' to install" << endl;
        return;
    }

will install it and try it again.

dsurver commented 2 weeks ago

nope, the warning goes away but still the same issue of infinite loop.

dsurver commented 2 weeks ago

the logs from the mavsdk_server are:

[06:39:25|Debug] MAVLink: critical: Preflight Fail: High Gyro Bias (system_impl.cpp:243)
[06:39:25|Error] notify_current_settings has no camera definition (camera_impl.cpp:2149)
[06:39:25|Error] notify_possible_setting_options has no camera definition (camera_impl.cpp:2192)
[06:39:25|Debug] COMMAND_LONG 522 to send to 1, 100 (mavlink_command_sender.cpp:112)
[06:39:25|Debug] Sent command 522 (mavlink_command_sender.cpp:407)
[06:39:25|Debug] Command ack for 522 (from: 1/1) does not match command 522 (to: 1/100) after 0.00392617 s (mavlink_command_sender.cpp:172)
[06:39:25|Debug] Received ack from 1/1 for not-existing command: 522! Ignoring... (mavlink_command_sender.cpp:283)
[06:39:26|Debug] Got timeout! (mavlink_command_sender.cpp:296)
[06:39:26|Warn ] sending again after 0.508501 s, retries to do: 3  (522). (mavlink_command_sender.cpp:320)

Do the following error related to the camera have anything to do the issue:

[06:39:25|Error] notify_current_settings has no camera definition (camera_impl.cpp:2149)
[06:39:25|Error] notify_possible_setting_options has no camera definition (camera_impl.cpp:2192)

and from the camera.py example from Mavsdk-python are:

Waiting for drone to connect...
-- Connected to drone!
Setting mode to 'PHOTO'
Camera mode: UNKNOWN
Setting mode failed with error code: TIMEOUT
Taking a photo
Couldn't take photo: TIMEOUT
JonasVautherin commented 2 weeks ago

and from the camera.py example from Mavsdk-python are

I think that the camera.py example will expect the camera to serve a camera definition file. Not sure if that gazebo addon does.

So I assume you are testing all this with px4-gazebo-headless? Is the camera_manager_plugin enabled (or did you manage to enable it)? Then the question would be: where does it send MAVLink (like is it multiplexed with the autopilot stream?)?

dsurver commented 2 weeks ago

yes i am testing with px4-gazebo-headless. If the camera_manager_plugin only needs to be enabled in the model sdf file then seems to be enabled.

regarding where does the plugin send mavlink, that should be in the sdf file right?

<plugin name="CameraManagerPlugin" filename="libgazebo_camera_manager_plugin.so">
            <robotNamespace>typhoon_h480</robotNamespace>
            <interval>1</interval>
            <width>3840</width>
            <height>2160</height>
            <maximum_zoom>8.0</maximum_zoom>
            <video_uri>udp://127.0.0.1:5600</video_uri>
            <system_id>1</system_id>
            <cam_component_id>100</cam_component_id>
            <mavlink_cam_udp_port>14530</mavlink_cam_udp_port>
        </plugin>

mavlink_cam_udp_port is 14530.

Now in the init script for px4 sitl i see this line referring to the camera in the commented out line but the mavlink stream start commands refers to onboard module. px4 init script

Does this mean that this is completely missing the camera module in the init script or wrong remote port?

JonasVautherin commented 2 weeks ago

Right, so px4-gazebo-headless changes this px4-rc.mavlink file (here) in order to redirect some of the mavlink streams to the docker host on ports 14540 (for MAVSDK) and 14550 (for QGC).

It seems like the camera plugin sends to 14530. It probably stays inside the container. But for MAVSDK's purpose, we would rather have both PX4 and the camera plugin send on the same stream (from the same port, to the same port). Is there a way to configure it such that the camera plugin sends MAVLink to PX4 and PX4 forwards it to its other ports? I think some kind of forwarding existed, maybe it could be used here 🤔.

@julianoes: would that be a valid use for PX4 forwarding?

dsurver commented 2 weeks ago

can it not be made to work like gimbal_plugin? is there a diference in how a camera manager interacts with px4 vs gimbal_manager <-> px4?

JonasVautherin commented 2 weeks ago

How is the gimbal plugin working there? It would be interesting to know the difference with the camera plugin indeed 👍

julianoes commented 2 weeks ago

@julianoes: would that be a valid use for PX4 forwarding?

Without having read everything, yes that might help.