Skip to content

Commit

Permalink
[INTEGRATION] prepare 7.5.0 rc1
Browse files Browse the repository at this point in the history
Change-Id: I4345c39a954269733e8a7015050e5749d7a2fda2
  • Loading branch information
ndessart committed Dec 14, 2022
1 parent 8cb0775 commit 3f55e74
Show file tree
Hide file tree
Showing 24 changed files with 503 additions and 259 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@ simulator) but may also be used to connect to physical drones. Like GroundSDK-iO
GroundSDK-Android, Olympe is based on arsdk-ng/arsdk-xml.

Olympe is part of the [Parrot Ground SDK](https://developer.parrot.com/) which allows any developer
to create its own mobile or desktop application for ANAFI and ANAFI Thermal drones.
to create its own mobile or desktop application for ANAFI, ANAFI Thermal and ANAFI AI drones.


## [Olympe Documentation](https://developer.parrot.com/docs/olympe/)
## [Olympe Documentation](https://developer.parrot.com/docs/olympe/installation.html)

* **[Olympe - Installation](https://developer.parrot.com/docs/olympe/installation.html)**
* **[Olympe - User guide](https://developer.parrot.com/docs/olympe/userguide.html)**
* **[Olympe - API Reference](https://developer.parrot.com/docs/olympe/olympeapi.html)**
* **[Olympe - SDK Messages Reference](https://developer.parrot.com/docs/olympe/arsdkng.html)**

## [Sphinx Documentation](https://developer.parrot.com/docs/sphinx/)
## [Sphinx Documentation](https://developer.parrot.com/docs/sphinx/installation.html)

* **[Sphinx - System requirements](https://developer.parrot.com/docs/sphinx/system-requirements.html)**
* **[Sphinx - System requirements](https://developer.parrot.com/docs/sphinx/system_requirements.html)**
* **[Sphinx - Installation](https://developer.parrot.com/docs/sphinx/installation.html)**
* **[Sphinx - Quick Start guide](https://developer.parrot.com/docs/sphinx/firststep.html)**
* **[Sphinx - Quick Start guide](https://developer.parrot.com/docs/sphinx/quickstart.html)**


## [Parrot developers forums](https://forum.developer.parrot.com/categories)

* **Olympe:** https://forum.developer.parrot.com/c/anafi/olympe
* **Sphinx:** https://forum.developer.parrot.com/c/sphinx
* **Parrot Anafi:** https://forum.developer.parrot.com/c/anafi/
* **Parrot Anafi Ai:** https://forum.developer.parrot.com/c/anafi-ai/

## License

Expand Down
19 changes: 18 additions & 1 deletion atom.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := olympe-base
LOCAL_CATEGORY_PATH := libs
LOCAL_DESCRIPTION := Olympe pure python module
LOCAL_DEPENDS_MODULES := python arsdkparser
LOCAL_DEPENDS_MODULES := python arsdkparser parrot-protobuf-extensions-proto protobuf-base
LOCAL_LIBRARIES := arsdkparser parrot-protobuf-extensions-proto

PRIVATE_OLYMPE_OUT_DIR=$(TARGET_OUT_STAGING)$(shell echo $${TARGET_DEPLOY_ROOT:-/usr})

Expand All @@ -24,6 +25,22 @@ LOCAL_COPY_FILES := \
$(__f):$(PRIVATE_OLYMPE_OUT_DIR)/lib/python/site-packages/$(strip $(patsubst src/%, %, $(__f))) \
)

# Install .proto files in python site-packages/olympe_protobuf staging directory
PRIVATE_OLYMPE_PROTOBUF_SRC_DIRS := $(PRIVATE_OLYMPE_OUT_DIR)/share/protobuf:$(PRIVATE_OLYMPE_OUT_DIR)/lib/python/site-packages
PRIVATE_OLYMPE_PROTOBUF_DST_DIR := $(PRIVATE_OLYMPE_OUT_DIR)/lib/python/site-packages/olympe_protobuf
define LOCAL_CMD_POST_INSTALL
while read -d ':' src_dir; do \
protobuf_src_files=$$(find $$src_dir -type f -name '*.proto'); \
protobuf_dst_files=$$(echo $$protobuf_src_files | xargs -I{} -d' ' bash -c "echo \"{}\" | \
sed 's#\s*$$src_dir#$(PRIVATE_OLYMPE_PROTOBUF_DST_DIR)#g'"); \
while read -ra src <&3 && read -ra dst <&4; do \
echo "$$src is in $$dst"; \
install -Dp -m0660 $$src $$dst; \
done 3<<<"$$protobuf_src_files" 4<<<"$$protobuf_dst_files"; \
done <<< $(PRIVATE_OLYMPE_PROTOBUF_SRC_DIRS):; \
echo $$protobuf_files;
endef

include $(BUILD_CUSTOM)

include $(CLEAR_VARS)
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ dependencies = [
"importlib_metadata; python_version < '3.8'",
"numpy",
"typing-protocol; python_version < '3.8'",
"protobuf==3.19.4",
"pycryptodomex",
"pytz",
"PyYAML",
Expand Down Expand Up @@ -87,11 +88,10 @@ olympe = "olympe.app:main"
top-levels = [
"olympe",
"olympe_deps",
"olympe_protobuf",
"arsdkparser.py",
"arsdk",
"google",
"logness",
"parrot",
"ulog.py",
"_ulog"
]
Expand Down
19 changes: 18 additions & 1 deletion src/olympe/arsdkng/cmd_itf.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ def matched_events(self):
def unmatched_events(self):
self._disconnected.unmatched_events()

def cancel(self):
disconnected_cancel = self._disconnected.cancel()
return super().cancel() or disconnected_cancel

def cancelled(self):
disconnected_cancelled = self._disconnected.cancelled()
return super().cancelled() and disconnected_cancelled


class Connect(Expectation):

Expand Down Expand Up @@ -207,6 +215,14 @@ def matched_events(self):
def unmatched_events(self):
self._connected.unmatched_events()

def cancel(self):
connected_cancel = self._connected.cancel()
return super().cancel() or connected_cancel

def cancelled(self):
connected_cancelled = self._connected.cancelled()
return super().cancelled() and connected_cancelled


class CommandInterfaceBase(LogMixin, AbstractScheduler):
def __init__(self, *, name=None, drone_type=0, proto_v_min=1, proto_v_max=3, **kwds):
Expand Down Expand Up @@ -244,7 +260,7 @@ def __init__(self, *, name=None, drone_type=0, proto_v_min=1, proto_v_max=3, **k
self._disconnect_future = None
self._declare_callbacks()
self._thread_loop.register_cleanup(self.destroy)
self.subscribe(
self._drone_manager_subscriber = self.subscribe(
self._on_connection_state_changed, drone_manager.connection_state()
)

Expand Down Expand Up @@ -573,6 +589,7 @@ def destroy(self):
if self._thread_loop is not None:
self._thread_loop.unregister_cleanup(self.destroy, ignore_error=True)
self._on_device_removed()
self._drone_manager_subscriber.unsubscribe()
self._scheduler.destroy()
if self._thread_loop is not None:
self._thread_loop.stop()
Expand Down
51 changes: 35 additions & 16 deletions src/olympe/arsdkng/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,20 @@


class PilotingCommand:
def __init__(self):
def __init__(self, time_function=None):
self.set_default_piloting_command()
if time_function:
self.time_function = time_function
else:
self.time_function = time.time

def update_piloting_command(self, roll, pitch, yaw, gaz, piloting_time):
self.roll = roll
self.pitch = pitch
self.yaw = yaw
self.gaz = gaz
self.piloting_time = piloting_time
self.initial_time = datetime.datetime.now()
self.initial_time = self.time_function()

def set_default_piloting_command(self):
self.roll = 0
Expand Down Expand Up @@ -92,7 +96,11 @@ def __init__(self,
self._ip_addr = ip_addr.encode('utf-8')
self._is_skyctrl = is_skyctrl
self._piloting = False
self._piloting_command = PilotingCommand()
self._time_function = time_function

self._piloting_command = PilotingCommand(
time_function=self._time_function)

self._backend_type = backend
if backend is BackendType.Net:
self._backend_class = CtrlBackendNet
Expand All @@ -108,8 +116,10 @@ def __init__(self,
proto_v_min=1,
proto_v_max=3,
device_addr=self._ip_addr)
if time_function is not None:
self._scheduler.set_time_function(time_function)

if self._time_function is not None:
self._scheduler.set_time_function(self._time_function)

self._connected_future = None
self._last_disconnection_time = None
# Setup piloting commands timer
Expand Down Expand Up @@ -259,6 +269,8 @@ def _disconnection_impl(self):
if not self.connected:
return f.set_result(True)

if self._disconnect_future is not None and not self._disconnect_future.done():
self._disconnect_future.cancel()
self._disconnect_future = f
res = od.arsdk_device_disconnect(self._device.arsdk_device)
if res != 0:
Expand Down Expand Up @@ -332,10 +344,10 @@ def _send_piloting_command(self):
if self._piloting_command.piloting_time:
# Check if piloting time since last pcmd order has been reached
diff_time = (
datetime.datetime.now() -
self._piloting_command.time_function() -
self._piloting_command.initial_time
)
if diff_time.total_seconds() >= self._piloting_command.piloting_time:
if diff_time >= self._piloting_command.piloting_time:
self._piloting_command.set_default_piloting_command()

# Flag to activate movement on roll and pitch. 1 activate, 0 deactivate
Expand Down Expand Up @@ -439,10 +451,11 @@ def piloting_pcmd(self, roll, pitch, yaw, gaz, piloting_time):
)
return self.piloting(roll, pitch, yaw, gaz, piloting_time)

async def _async_discover_device(self):
async def _async_discover_device(self, deadline):
# Try to identify the device type we are attempting to connect to...
await self._backend.ready()
discovery = self._discovery_class(self._backend, ip_addr=self._ip_addr)
timeout = (deadline - time.time()) / 2
discovery = self._discovery_class(self._backend, ip_addr=self._ip_addr, timeout=timeout)
device = await discovery.async_get_device()
if device is not None:
return device, discovery
Expand All @@ -451,16 +464,17 @@ async def _async_discover_device(self):
self.logger.info(f"Net discovery failed for {self._ip_addr}")
self.logger.info(f"Trying 'NetRaw' discovery for {self._ip_addr} ...")
assert await discovery.async_stop()
discovery = DiscoveryNetRaw(self._backend, ip_addr=self._ip_addr)
timeout = (deadline - time.time()) / 4
discovery = DiscoveryNetRaw(self._backend, ip_addr=self._ip_addr, timeout=timeout)
device = await discovery.async_get_device()
if device is None:
await discovery.async_stop()
return device, discovery

async def _async_get_device(self):
async def _async_get_device(self, deadline):
if self._device is not None:
return True
device, discovery = await self._async_discover_device()
device, discovery = await self._async_discover_device(deadline)

if device is None:
self.logger.info(f"Unable to discover the device: {self._ip_addr}")
Expand Down Expand Up @@ -490,10 +504,12 @@ def _connect_impl(self, deadline):
device_id = b""

device_conn_cfg = od.struct_arsdk_device_conn_cfg(
ctypes.create_string_buffer(b"arsdk-ng"), ctypes.create_string_buffer(b"desktop"),
ctypes.create_string_buffer(b"olympe"), ctypes.create_string_buffer(b"desktop"),
ctypes.create_string_buffer(bytes(device_id)), ctypes.create_string_buffer(req))

# Send connection command
if self._connect_future is not None and not self._connect_future.done():
self._connect_future.cancel()
self._connect_future = Future(self._thread_loop)
res = od.arsdk_device_connect(
self._device.arsdk_device,
Expand Down Expand Up @@ -528,8 +544,11 @@ async def _do_connect(self, timeout, retry):
self.logger.error(f"'{self._ip_addr_str} connection timed out")
return False
self.logger.debug(f"Discovering device {self._ip_addr_str} ...")
if not await self._async_get_device():
if not await self._async_get_device(deadline):
self.logger.debug(f"Discovering device {self._ip_addr_str} failed")
if deadline < (time.time() + backoff):
self.logger.error(f"'{self._ip_addr_str} connection (would) have timed out")
return False
await self._thread_loop.asleep(backoff)
backoff *= 2.
continue
Expand Down Expand Up @@ -673,12 +692,12 @@ def _on_device_removed(self):
self._stop_piloting_impl()
self._disconnection_impl()
self._last_disconnection_time = time.time()
self._piloting_command = PilotingCommand()
self._piloting_command = PilotingCommand(time_function=self._time_function)
super()._on_device_removed()

def _reset_instance(self):
self._piloting = False
self._piloting_command = PilotingCommand()
self._piloting_command = PilotingCommand(time_function=self._time_function)
self._device = None
self._device_name = None
self._discovery = None
Expand Down
2 changes: 1 addition & 1 deletion src/olympe/arsdkng/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ def stop(self):
if res < 0:
self.logger.error(f"arsdk_backend_mux_stop_listen: {res}")
ret = False
self._backend.destroy()
self.connected = False
self._listening = False
return ret
Expand Down Expand Up @@ -352,3 +351,4 @@ def destroy(self):
"""
self.stop()
super().destroy()
self._backend.destroy()
Loading

0 comments on commit 3f55e74

Please sign in to comment.