MAVSDK-Python icon indicating copy to clipboard operation
MAVSDK-Python copied to clipboard

'System' object has no attribute 'channel',The gripper does not work properly.

Open Yan-Yiyang opened this issue 1 year ago • 21 comments

Use Ubuntu 22.04 PX4 v1.14 MAVSDK 2.0.1 Hey, I want to control my gripper with this code

from mavsdk import System
from mavsdk.gripper import Gripper
import asyncio


async def run():
    drone = System()
    await drone.connect(system_address="udp://:14540")
    print("正在连接无人机...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print("-- 无人机已连接!")
            break

    print("正在等待定位...")
    async for health in drone.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("-- 定位已准备好!")
            break
    gripper = Gripper(drone)
    await gripper.release(1)

asyncio.run(run())

But,this error is generated

Traceback (most recent call last): File "/home/yyy/桌面/模拟测试用/test.py", line 23, in asyncio.run(run()) File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run return loop.run_until_complete(main) File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete return future.result() File "/home/yyy/桌面/模拟测试用/test.py", line 20, in run gripper = Gripper(drone) File "/home/yyy/.local/lib/python3.10/site-packages/mavsdk/_base.py", line 10, in init self._init_plugin(async_plugin_manager) File "/home/yyy/.local/lib/python3.10/site-packages/mavsdk/_base.py", line 17, in _init_plugin self._setup_stub(async_plugin_manager.channel) AttributeError: 'System' object has no attribute 'channel'

Yan-Yiyang avatar Mar 04 '24 03:03 Yan-Yiyang

Right, thanks for the note. That's a new plugin.

Needs adding here:

https://github.com/mavlink/MAVSDK-Python/blob/main/mavsdk/system.py#L8-L38

And: https://github.com/mavlink/MAVSDK-Python/blob/main/mavsdk/system.py#L130-L161

julianoes avatar Mar 04 '24 04:03 julianoes

Like this? I added the gripper behind gimbal.

from . import action
from . import action_server
from . import calibration
from . import camera
from . import camera_server
from . import component_information
from . import component_information_server
from . import core
from . import failure
from . import follow_me
from . import ftp
from . import geofence
from . import gimbal
from . import gripper
from . import info
from . import log_files
from . import manual_control
from . import mission
from . import mission_raw
from . import mission_raw_server
from . import mocap
from . import offboard
from . import param
from . import param_server
from . import rtk
from . import server_utility
from . import shell
from . import telemetry
from . import telemetry_server
from . import tracking_server
from . import transponder
from . import tune

from . import bin
        self._plugins = {}
        self._plugins["action"] = action.Action(plugin_manager)
        self._plugins["action_server"] = action_server.ActionServer(plugin_manager)
        self._plugins["calibration"] = calibration.Calibration(plugin_manager)
        self._plugins["camera"] = camera.Camera(plugin_manager)
        self._plugins["camera_server"] = camera_server.CameraServer(plugin_manager)
        self._plugins["component_information"] = component_information.ComponentInformation(plugin_manager)
        self._plugins["component_information_server"] = component_information_server.ComponentInformationServer(plugin_manager)
        self._plugins["core"] = core.Core(plugin_manager)
        self._plugins["failure"] = failure.Failure(plugin_manager)
        self._plugins["follow_me"] = follow_me.FollowMe(plugin_manager)
        self._plugins["ftp"] = ftp.Ftp(plugin_manager)
        self._plugins["geofence"] = geofence.Geofence(plugin_manager)
        self._plugins["gimbal"] = gimbal.Gimbal(plugin_manager)
        self._plugins["gripper"] = gripper.Gripper(plugin_manager)
        self._plugins["info"] = info.Info(plugin_manager)
        self._plugins["log_files"] = log_files.LogFiles(plugin_manager)
        self._plugins["manual_control"] = manual_control.ManualControl(plugin_manager)
        self._plugins["mission"] = mission.Mission(plugin_manager)
        self._plugins["mission_raw"] = mission_raw.MissionRaw(plugin_manager)
        self._plugins["mission_raw_server"] = mission_raw_server.MissionRawServer(plugin_manager)
        self._plugins["mocap"] = mocap.Mocap(plugin_manager)
        self._plugins["offboard"] = offboard.Offboard(plugin_manager)
        self._plugins["param"] = param.Param(plugin_manager)
        self._plugins["param_server"] = param_server.ParamServer(plugin_manager)
        self._plugins["rtk"] = rtk.Rtk(plugin_manager)
        self._plugins["server_utility"] = server_utility.ServerUtility(plugin_manager)
        self._plugins["shell"] = shell.Shell(plugin_manager)
        self._plugins["telemetry"] = telemetry.Telemetry(plugin_manager)
        self._plugins["telemetry_server"] = telemetry_server.TelemetryServer(plugin_manager)
        self._plugins["tracking_server"] = tracking_server.TrackingServer(plugin_manager)
        self._plugins["transponder"] = transponder.Transponder(plugin_manager)
        self._plugins["tune"] = tune.Tune(plugin_manager)

Yan-Yiyang avatar Mar 04 '24 04:03 Yan-Yiyang

Can you make a pull request with the change?

julianoes avatar Mar 04 '24 17:03 julianoes

Did you try it? Does it work?

JonasVautherin avatar Mar 04 '24 21:03 JonasVautherin

Changing it the way I did it above still produces the same error. I added these to https://github.com/mavlink/MAVSDK-Python/blob/main/mavsdk/system.py#L163-L352.

@property
    def gripper(self) -> gripper.Gripper:
        if "gripper" not in self._plugins:
            raise RuntimeError(self.error_uninitialized("Gripper"))
        return self._plugins["gripper"]

Then call it like this.

import asyncio
from mavsdk import System


async def run():
    drone = System()
    await drone.connect(system_address="udp://:14540")

    print("正在连接无人机...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print("--无人机已连接!")
            break

    print("等待确认位置信息...")
    async for health in drone.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("--位置信息已确认!")
            break

    await drone.gripper.release(1)
asyncio.run(run())

The program seems to run, but still reports errors, and I don't know what's wrong.(I have turned on the parameters related to Payload Deliverer and have set AUX1 to gripper)

Traceback (most recent call last):
  File "/home/yyy/code/test.py", line 22, in <module>
    asyncio.run(run())
  File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/yyy/code/test.py", line 21, in run
    await drone.gripper.release(1)
  File "/home/yyy/.local/lib/python3.8/site-packages/mavsdk/gripper.py", line 278, in release
    raise GripperError(result, "release()", instance)
mavsdk.gripper.GripperError: TIMEOUT: 'Timeout'; origin: release(); params: (1,)

The reported error is copied from sitl, which is the same as running it on the real plane.

Yan-Yiyang avatar Mar 05 '24 05:03 Yan-Yiyang

By the way, you also need to make sure the gripper stuff is available in PX4. You can see how it is enabled for SITL here: https://github.com/PX4/PX4-Autopilot/blob/6f9a37824732a676bf082628ea5ac4b243b44c64/boards/px4/sitl/default.px4board#L45

julianoes avatar Mar 05 '24 23:03 julianoes

Thank you, I noticed this part. Gripper has been enabled in all the tests I conducted.That may not be the problem.

Yan-Yiyang avatar Mar 06 '24 02:03 Yan-Yiyang

Try https://github.com/mavlink/MAVSDK-Python/releases/tag/2.1.0.

julianoes avatar Mar 07 '24 03:03 julianoes

After updating to the latest version, I found this error reported on the cmd window of mavsdk server. MAVSDK version: v2.4.1

[07:48:52|Warn ] Received ack for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[07:48:53|Warn ] sending again after 0.569896 s, retries to do: 3  (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[07:48:53|Warn ] Received ack for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[07:48:53|Warn ] sending again after 1.09786 s, retries to do: 2  (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[07:48:53|Warn ] Received ack for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[07:48:54|Warn ] sending again after 1.62407 s, retries to do: 1  (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[07:48:54|Warn ] Received ack for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[07:48:54|Error] Retrying failed (211) (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:339)

Yan-Yiyang avatar Mar 10 '24 11:03 Yan-Yiyang

Interesting, so 211, is the MAV_CMD_DO_GRIPPER command.

What are you trying to do, or how are you reproducing this? And against SITL or a real drone? If you give me the steps to reproduce this, I'll give it a go.

julianoes avatar Mar 10 '24 23:03 julianoes

Real drone with PX4 v1.14 Release(Only the payload_deliverer module is additionally enabled) ,MAVSDK-Python v2.1.0 and latest version of mavsdk server.

This error can be seen on Windows because only on Windows I can see the mavsdk server window. But I think this problem occurs on both Linux and WIndows, because the Python error message "Timeout" appears on both. mavsdk.gripper.GripperError: TIMEOUT: 'Timeout'; origin: release(); params: (1,) Here is my test code on Windows.

from mavsdk import System
import asyncio


async def run():
    drone = System(mavsdk_server_address='localhost', port=50051)
    await drone.connect()
    print("正在连接无人机...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print("-- 无人机已连接!")
            break

    print("正在等待定位...")
    async for health in drone.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("-- 定位已准备好!")
            break
    await drone.gripper.release(1)


asyncio.run(run())

Yan-Yiyang avatar Mar 11 '24 02:03 Yan-Yiyang

I'll have to try to reproduce it then. I'll put it on my todo list. If this is urgent to you, consider github sponsoring.

julianoes avatar Mar 11 '24 17:03 julianoes

FYI @potaito

julianoes avatar Mar 11 '24 17:03 julianoes

This error can be seen on Windows because only on Windows I can see the mavsdk server window. But I think this problem occurs on both Linux and WIndows, because the Python error message "Timeout" appears on both. mavsdk.gripper.GripperError: TIMEOUT: 'Timeout'; origin: release(); params: (1,) Here is my test code on Windows.

Does this winch ACK the command? Because that's when MAVSDK runs into a timeout, if it gets no confirmation for the winch or gripper commands.

potaito avatar Mar 12 '24 07:03 potaito

This issue has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there:

https://discuss.px4.io/t/unable-to-control-drone-via-mavsdk-though-qgc-works-fine/34699/21

DronecodeBot avatar Mar 12 '24 17:03 DronecodeBot

This error can be seen on Windows because only on Windows I can see the mavsdk server window. But I think this problem occurs on both Linux and WIndows, because the Python error message "Timeout" appears on both. Here is my test code on Windows.mavsdk.gripper.GripperError: TIMEOUT: 'Timeout'; origin: release(); params: (1,)

Does this winch ACK the command? Because that's when MAVSDK runs into a timeout, if it gets no confirmation for the winch or gripper commands.

Problems will still arise.

[09:04:54|Warn ] Received ack for not-existing command: 42600! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[09:04:54|Warn ] sending again after 1.02727 s, retries to do: 3  (42600). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[09:04:55|Warn ] Received ack for not-existing command: 42600! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[09:04:55|Warn ] sending again after 1.63693 s, retries to do: 2  (42600). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[09:04:55|Warn ] Received ack for not-existing command: 42600! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[09:04:56|Warn ] sending again after 2.42667 s, retries to do: 1  (42600). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312)
[09:04:56|Warn ] Received ack for not-existing command: 42600! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:283)
[09:04:57|Error] Retrying failed (42600) (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:339)

Yan-Yiyang avatar Mar 13 '24 13:03 Yan-Yiyang

@julianoes ah, the problem in this case is that the ACK for the DO_WINCH command (42600) is being dropped because it's not recognized :thinking:

potaito avatar Mar 14 '24 08:03 potaito

Yeah that's where the weirdness comes in, I can use gripper normally on QGC with button, missions or joystick, but once I use mavsdk I can't control gripper. I think they're both controlled via MavLink and there shouldn't be this discrepancy.

Yan-Yiyang avatar Mar 14 '24 09:03 Yan-Yiyang

I suspect we use int16_t sometimes instead of uint16_tsomewhere for the command.

julianoes avatar Mar 19 '24 03:03 julianoes

Can you get more output using export MAVSDK_COMMAND_DEBUGGING=1?

julianoes avatar Mar 19 '24 04:03 julianoes

Here's the error now.

[C:\Users\yanyi\OneDrive - link.tyut.edu.cn\对地\代码\Python\2024>.\mavsdk_server_win32.exe -p 50051 -d serial://COM6:57600 [09:24:37|Info ] MAVSDK version: v2.4.0 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavsdk_impl.cpp:26) [09:24:37|Debug] Command debugging is on. (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_receiver.cpp:26) [09:24:37|Info ] Waiting to discover system on serial://COM6:57600... (D:\a\MAVSDK\MAVSDK\src\mavsdk_server\src\connection_initiator.h:20) [09:24:37|Debug] New system ID: 1 Comp ID: 1 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavsdk_impl.cpp:737) [09:24:37|Debug] Command debugging is on. (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:15) [09:24:37|Debug] Component Autopilot (1) added. (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\system_impl.cpp:389) [09:24:37|Debug] MAVLink: info: GCS connection regained (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\system_impl.cpp:257) [09:24:37|Warn ] Vehicle type changed (new type: 1, old type: 0) (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\system_impl.cpp:231) [09:24:37|Debug] Discovered 1 component(s) (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\system_impl.cpp:564) [09:24:37|Debug] COMMAND_LONG 520 to send to 1, 1 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:104) [09:24:37|Info ] System discovered (D:\a\MAVSDK\MAVSDK\src\mavsdk_server\src\connection_initiator.h:62) [09:24:37|Info ] Server started (D:\a\MAVSDK\MAVSDK\src\mavsdk_server\src\grpc_server.cpp:165) [09:24:37|Info ] Server set to listen on 0.0.0.0:50051 (D:\a\MAVSDK\MAVSDK\src\mavsdk_server\src\grpc_server.cpp:166) [09:24:38|Debug] Sent command 520 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:400) [09:24:38|Debug] Received command ack for 520 with result 0 after 0.894296 s (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:177) [09:25:04|Debug] COMMAND_LONG 211 to send to 1, 169 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:104) [09:25:04|Debug] Sent command 211 (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:400) [09:25:05|Debug] Command ack for 211 (from: 1/1) does not match command 211 (to: 1/169) after 0.4283 s (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:164) [09:25:05|Debug] Received ack from 1/1 for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:278) [09:25:05|Warn ] sending again after 0.71919 s, retries to do: 3 (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312) [09:25:05|Debug] Command ack for 211 (from: 1/1) does not match command 211 (to: 1/169) after 1.02757 s (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:164) [09:25:05|Debug] Received ack from 1/1 for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:278) [09:25:06|Warn ] sending again after 1.28832 s, retries to do: 2 (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312) [09:25:06|Debug] Command ack for 211 (from: 1/1) does not match command 211 (to: 1/169) after 1.61371 s (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:164) [09:25:06|Debug] Received ack from 1/1 for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:278) [09:25:06|Warn ] sending again after 1.88858 s, retries to do: 1 (211). (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:312) [09:25:07|Debug] Command ack for 211 (from: 1/1) does not match command 211 (to: 1/169) after 2.33692 s (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:164) [09:25:07|Debug] Received ack from 1/1 for not-existing command: 211! Ignoring... (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:278) [09:25:07|Error] Retrying failed (211) (D:\a\MAVSDK\MAVSDK\src\mavsdk\core\mavlink_command_sender.cpp:339)]

Yan-Yiyang avatar Mar 21 '24 13:03 Yan-Yiyang