Skip to content

Commit

Permalink
Add debug vector send capability (#118)
Browse files Browse the repository at this point in the history
* Added support for debug vect

* added debug_vect to send_debug_message()

* final testing complete

* added a better example for debug

* remove unwanted file changes

* fixed stale comments and warnings for PR

* remooved unwanted mission report

* Fixed spelling errors and error handling issues

* final cleanup for send_debug.py

* final testing complete

* Gramatical fixes

* Updated changelog and bumped project version

* Fix ci pipeline

Co-authored-by: Grant Phillips <[email protected]>
Co-authored-by: Grant Phillips <[email protected]>
Co-authored-by: Evan Palmer <[email protected]>
  • Loading branch information
4 people authored Sep 4, 2022
1 parent 090281d commit 905a161
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
python -m pip install --upgrade pip
python -m pip install tox tox-gh-actions
- name: Test implementation
run: tox
run: python -m tox

package:
name: Build & publish package
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ utilizes `Semantic Versioning`_ for project versioning.

.. _Semantic Versioning: https://semver.org/

[v1.1.0] - 2022-09-04
---------------------

Added
^^^^^

- Support for sending debug vectors: `PR #118`_

.. _PR #118: https://github.com/unl-nimbus-lab/pymavswarm/pull/118

[v1.0.0] - 2022-08-13
---------------------
Expand Down
105 changes: 105 additions & 0 deletions examples/send_debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# pymavswarm is an interface for swarm control and interaction
# Copyright (C) 2022 Grant Phillips

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from __future__ import annotations

import time
from argparse import ArgumentParser
from concurrent.futures import Future
from typing import Any

from pymavswarm import MavSwarm


def parse_args() -> Any:
"""
Parse the script arguments.
:return: argument namespace
:rtype: Any
"""
parser = ArgumentParser()
parser.add_argument(
"port", type=str, help="port to establish a MAVLink connection over"
)
parser.add_argument("baud", type=int, help="baudrate to establish a connection at")
parser.add_argument("name", type=str, help="debug value name")
parser.add_argument("data1", type=float, help="debug vector payload1")
parser.add_argument("data2", type=float, help="debug vector payload2")
parser.add_argument("data3", type=float, help="debug vector payload3")
return parser.parse_args()


# Define a callback to attach to a future
def print_message_response_cb(future: Future) -> None:
"""
Print the result of the future.
:param future: message execution future
:type future: Future
"""
responses = future.result()

if isinstance(responses, list):
for response in responses:
print(
f"Result of {response.message_type} message sent to "
f"({response.target_agent_id}): {response.code}"
)
else:
print(
f"Result of {responses.message_type} message sent to "
f"({responses.target_agent_id}): {responses.code}"
)

return


def main() -> None:
"""Demonstrate how to send a debug vector."""
# Parse the script arguments
args = parse_args()

# Create a new MavSwarm instance
mavswarm = MavSwarm()

# Attempt to create a new MAVLink connection
if not mavswarm.connect(args.port, args.baud):
return

# Wait for the swarm to auto-register new agents
while not list(filter(lambda agent_id: agent_id[1] == 1, mavswarm.agent_ids)):
print("Waiting for the system to recognize agents in the network...")
time.sleep(0.5)

# Send a debug message to all agents in the swarm
future = mavswarm.send_debug_message(
args.name, [args.data1, args.data2, args.data3]
)
future.add_done_callback(print_message_response_cb)

# Wait for the arm command to complete
while not future.done():
pass

# Disconnect from the swarm
mavswarm.disconnect()

return


if __name__ == "__main__":
main()
26 changes: 20 additions & 6 deletions pymavswarm/mavswarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,7 @@ def executor(agent_id: AgentID) -> None:
def send_debug_message(
self,
name: str,
value: int | float,
value: int | float | list,
agent_ids: AgentID | list[AgentID] | None = None,
retry: bool = False,
message_timeout: float = 2.5,
Expand All @@ -1133,7 +1133,7 @@ def send_debug_message(
:param name: debug message name
:type name: str
:param value: debug message value
:type value: int | float
:type value: int | float | list
:param agent_ids: optional list of target agent IDs, defaults to None
:type agent_ids: AgentID | list[AgentID] | None,
optional
Expand All @@ -1152,9 +1152,14 @@ def send_debug_message(
if not isinstance(name, str):
raise TypeError(f"Invalid name provided. Expected string, got {type(name)}")

if not isinstance(value, int) and not isinstance(value, float):
if (
not isinstance(value, int)
and not isinstance(value, float)
and not isinstance(value, list)
):
raise TypeError(
f"Invalid value provided. Expected an int or a float, got {type(value)}"
"Invalid value provided. Expected an int, float or list, got "
f"{type(value)}"
)

def executor(agent_id: AgentID) -> None:
Expand All @@ -1163,15 +1168,24 @@ def executor(agent_id: AgentID) -> None:
self._connection.mavlink_connection.target_system = agent_id[0]
self._connection.mavlink_connection.target_component = agent_id[1]

# Send flight mode
# Send debug message
if isinstance(value, int):
self._connection.mavlink_connection.mav.named_value_int_send(
int(time.time()), str.encode(name), value
)
else:
elif isinstance(value, float):
self._connection.mavlink_connection.mav.named_value_float_send(
int(time.time()), str.encode(name), value
)
elif isinstance(value, list):
if len(value) != 3:
raise ValueError(
"Invalid number of debug vector elements provided. "
f"Expected 3, got {len(value)}"
)
self._connection.mavlink_connection.mav.debug_vect_send(
str.encode(name), int(time.time()), *value
)

return

Expand Down
6 changes: 3 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[metadata]
name = pymavswarm
version = 1.0.0
version = 1.1.0
description = Python library used to communicate with multiple UAS simultaneously using MAVLink
long_description = file: README.md
long_description_content_type = text/markdown
long_description = file: README.rst
long_description_content_type = text/x-rst
url = https://github.com/unl-nimbus-lab/pymavswarm
author = Evan Palmer
author_email = [email protected]
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ commands = coverage run -m unittest

[testenv:coverage-report]
deps = coverage
commands = coverage report --skip-covered --skip-empty
commands =
coverage combine
coverage report --skip-covered --skip-empty

[testenv:lint]
skip_install = true
Expand Down

0 comments on commit 905a161

Please sign in to comment.