Skip to content

Commit

Permalink
Fix dronekit code mostly related to connecting to the drone #23
Browse files Browse the repository at this point in the history
  • Loading branch information
RexBerry committed Oct 2, 2024
1 parent 8cd938b commit 711f739
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 33 deletions.
6 changes: 4 additions & 2 deletions flight/odlc_boundaries/search_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ async def run() -> None:
try:
# create a drone object
logging.info("Waiting for drone to connect...")
drone: dronekit.Vehicle = dronekit.connect(sitl.connection_string())
drone: dronekit.Vehicle = dronekit.connect("tcp:127.0.0.1:5762")
drone.wait_ready(True)

logging.info("Waiting for pre-arm checks to pass...")
Expand Down Expand Up @@ -210,7 +210,9 @@ async def run() -> None:
)

# Generate search path
BUFFER_DISTANCE: int = -40 # use height/2 of camera image area on ground as buffer distance
BUFFER_DISTANCE: int = (
-40
) # use height/2 of camera image area on ground as buffer distance
search_paths: list[tuple[float, float]] = generate_search_paths(
data_search_area_boundary_utm, BUFFER_DISTANCE
)
Expand Down
6 changes: 3 additions & 3 deletions flight/waypoint/goto.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ async def move_to(
a float containing the requested longitude to move to
altitude: float
a float containing the requested altitude to go to in meters
airspeed: float, optional
a float containing the requested airspeed in meters per second;
if not specified, lets DroneKit decide the airspeed
airspeed: float, default None
a float containing the requested airspeed in meters per second,
or None to let DroneKit decide the airspeed
"""
drone.simple_goto(
dronekit.LocationGlobalRelative(latitude, longitude, altitude),
Expand Down
63 changes: 38 additions & 25 deletions state_machine/drone.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Drone:
----------
address : str
The address used to connect to the drone.
baud : int | None
The baud rate, or None to use the default.
is_connected
odlc_scan : bool
A boolean to tell if the odlc zone needs to be scanned, used the
Expand All @@ -27,15 +29,17 @@ class Drone:
-------
__init__(connection_string: str) -> None
Initialize a new Drone object, but do not connect to a drone.
connect_drone(self) -> Awaitable[None]
Connect to a drone.
is_connected(self) -> bool
Checks if a drone has been connected to.
vehicle(self) -> dronekit.Vehicle
Get the Dronekit Vehicle object owned by this Drone object.
is_connected(self) -> bool
Checks if a drone has been connected to.
connect_drone(self) -> Awaitable[None]
Connect to a drone.
close(self) -> Awaitable[none]
Close the owned DroneKit Vehicle object.
"""

def __init__(self, address: str = "") -> None:
def __init__(self, address: str = "", baud: int | None = None) -> None:
"""
Initialize a new Drone object, but do not connect to a drone.
Expand All @@ -44,29 +48,14 @@ def __init__(self, address: str = "") -> None:
address : str, default ""
The address of the drone to connect to when the `connect_drone()`
method is called.
baud : int, default None
The baud rate, or None to use the default.
"""
self._vehicle: dronekit.Vehicle | None = None
self.address: str = address
self.baud: int | None = baud
self.odlc_scan: bool = True

async def connect_drone(self) -> None:
"""Connect to a drone. This operation is idempotent.
Raises
------
RuntimeError
If no connection address has been set.
"""
if self.is_connected:
return

if len(self.address) == 0:
raise RuntimeError("no connection address specified")

vehicle: dronekit.Vehicle = dronekit.connect(self.address)
vehicle.wait_ready(True) # this doesn't run asynchronously
self._vehicle = vehicle

@property
def is_connected(self) -> bool:
"""Checks if a drone has been connected to.
Expand All @@ -80,7 +69,7 @@ def is_connected(self) -> bool:

@property
def vehicle(self) -> dronekit.Vehicle:
"""Get the Dronekit Vehicle object owned by this Drone object.
"""Get the DroneKit Vehicle object owned by this Drone object.
Returns
-------
Expand All @@ -94,5 +83,29 @@ def vehicle(self) -> dronekit.Vehicle:
"""
vehicle: dronekit.Vehicle | None = self._vehicle
if vehicle is None:
raise AttributeError("we haven't connected to the drone yet")
raise RuntimeError("we haven't connected to the drone yet")
return vehicle

async def connect_drone(self) -> None:
"""Connect to a drone. This operation is idempotent.
Raises
------
RuntimeError
If no connection address has been set.
"""
if self.is_connected:
return

if len(self.address) == 0:
raise RuntimeError("no connection address specified")

vehicle: dronekit.Vehicle = (
dronekit.connect(self.address, wait_ready=True)
if self.baud is None
else dronekit.connect(self.address, wait_ready=True, baud=self.baud)
)

async def close(self) -> None:
"""Close the owned DroneKit Vehicle object."""
self.vehicle.close()
7 changes: 4 additions & 3 deletions state_machine/flight_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ async def run_manager(
standard_object_count : int, default DEFAULT_STANDARD_OBJECT_COUNT
The number of standard objects to attempt to find.
"""
sitl: dronekit_sitl.SITL | None = None

if sim_flag:
sitl = dronekit_sitl.start_default()
self.drone.address = sitl.connection_string()
self.drone.address = "tcp:127.0.0.1:5762"
else:
self.drone.address = "serial:///dev/ttyFTDI:921600"
self.drone.address = "/dev/ttyFTDI"
self.drone.baud = 921600

try:
flight_settings_obj: FlightSettings = FlightSettings(
Expand Down Expand Up @@ -103,6 +103,7 @@ async def run_manager(
state_machine_task.cancel()
await self._graceful_exit()
finally:
await self.drone.close()
if sitl is not None:
sitl.stop()

Expand Down

0 comments on commit 711f739

Please sign in to comment.