Skip to content

Commit

Permalink
add missing impl
Browse files Browse the repository at this point in the history
  • Loading branch information
s5suzuki committed Oct 3, 2024
1 parent 94ad042 commit a38e664
Show file tree
Hide file tree
Showing 34 changed files with 801 additions and 166 deletions.
2 changes: 0 additions & 2 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ exclude_lines =

pragma: no cover

def update_geometry
async def update_geometry_async

[run]
omit =
Expand Down
6 changes: 6 additions & 0 deletions pyautd3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
Clear,
DebugSettings,
DebugType,
FixedCompletionTime,
FixedUpdateRate,
FociSTM,
ForceFan,
GainSTM,
GainSTMMode,
PhaseCorrection,
PulseWidthEncoder,
ReadsFPGAState,
Silencer,
Expand Down Expand Up @@ -53,13 +56,16 @@ def tracing_init() -> None:
"tracing_init",
"Controller",
"AUTD3",
"PhaseCorrection",
"Drive",
"EmitIntensity",
"Phase",
"phase_rad",
"SamplingConfig",
"Clear",
"Silencer",
"FixedCompletionTime",
"FixedUpdateRate",
"DebugSettings",
"DebugType",
"ReadsFPGAState",
Expand Down
5 changes: 0 additions & 5 deletions pyautd3/autd_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ def __init__(self: "InvalidDatagramTypeError") -> None:
super().__init__("Invalid datagram type")


class InvalidPlotConfigError(AUTDError):
def __init__(self: "InvalidPlotConfigError") -> None:
super().__init__("Invalid plot config type")


class CantBeZeroError(AUTDError):
def __init__(self: "CantBeZeroError", v: int) -> None:
super().__init__(f"Value must be greater than 0: {v}")
18 changes: 11 additions & 7 deletions pyautd3/controller/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from pyautd3.driver.firmware_version import FirmwareInfo
from pyautd3.driver.geometry import Device, Geometry
from pyautd3.driver.link import Link, LinkBuilder
from pyautd3.driver.utils import _validate_nonzero_u32
from pyautd3.native_methods.autd3capi import ControllerBuilderPtr, ControllerPtr, RuntimePtr
from pyautd3.native_methods.autd3capi import NativeMethods as Base
from pyautd3.native_methods.autd3capi_driver import DatagramPtr, GeometryPtr, HandlePtr, ResultI32
Expand Down Expand Up @@ -45,7 +46,12 @@ def with_send_interval(self: "_Builder", interval: timedelta) -> "_Builder":
self._ptr = Base().controller_builder_with_send_interval(self._ptr, int(interval.total_seconds() * 1000 * 1000 * 1000))
return self

def with_timer_resolution(self: "_Builder", resolution: int) -> "_Builder":
def with_receive_interval(self: "_Builder", interval: timedelta) -> "_Builder":
self._ptr = Base().controller_builder_with_receive_interval(self._ptr, int(interval.total_seconds() * 1000 * 1000 * 1000))
return self

def with_timer_resolution(self: "_Builder", resolution: int | None) -> "_Builder":
resolution = 0 if resolution is None else _validate_nonzero_u32(resolution)
self._ptr = Base().controller_builder_with_timer_resolution(self._ptr, resolution)
return self

Expand Down Expand Up @@ -265,7 +271,7 @@ def get_firmware_info(i: int) -> FirmwareInfo:

async def close_async(self: "Controller") -> None:
r: ResultI32 | None = None
if self._handle._0 is not None and self._ptr._0 is not None:
if self._handle._0:
future: asyncio.Future = asyncio.Future()
loop = asyncio.get_event_loop()
ffi_future = Base().controller_close(self._ptr)
Expand All @@ -275,21 +281,19 @@ async def close_async(self: "Controller") -> None:
),
)
r = await future
self._ptr._0 = None
if self._handle._0 is not None:
Base().delete_runtime(self._runtime)
self._ptr._0 = None
self._runtime._0 = None
self._handle._0 = None
if r is not None:
_validate_int(r)

def close(self: "Controller") -> None:
r: ResultI32 | None = None
if self._handle._0 is not None and self._ptr._0 is not None:
r = Base().wait_result_i_32(self._handle, Base().controller_close(self._ptr))
self._ptr._0 = None
if self._handle._0 is not None:
r = Base().wait_result_i_32(self._handle, Base().controller_close(self._ptr))
Base().delete_runtime(self._runtime)
self._ptr._0 = None
self._runtime._0 = None
self._handle._0 = None
if r is not None:
Expand Down
6 changes: 5 additions & 1 deletion pyautd3/driver/datagram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@
from .datagram import Datagram
from .debug import DebugSettings, DebugType
from .force_fan import ForceFan
from .phase_corr import PhaseCorrection
from .pulse_width_encoder import PulseWidthEncoder
from .reads_fpga_state import ReadsFPGAState
from .segment import SwapSegment
from .silencer import Silencer
from .silencer import FixedCompletionTime, FixedUpdateRate, Silencer
from .stm import FociSTM, GainSTM, GainSTMMode
from .synchronize import Synchronize

__all__ = [
"Clear",
"Silencer",
"FixedCompletionTime",
"FixedUpdateRate",
"DebugSettings",
"DebugType",
"ReadsFPGAState",
Expand All @@ -31,6 +34,7 @@
"GainSTMMode",
"SwapSegment",
"PulseWidthEncoder",
"PhaseCorrection",
]


Expand Down
42 changes: 42 additions & 0 deletions pyautd3/driver/datagram/modulation/fir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ctypes
from collections.abc import Iterable
from typing import Generic, TypeVar

import numpy as np

from pyautd3.driver.datagram.modulation.modulation import ModulationBase
from pyautd3.driver.datagram.modulation.radiation_pressure import IntoModulationRadiationPressure
from pyautd3.native_methods.autd3capi import NativeMethods as Base
from pyautd3.native_methods.autd3capi_driver import ModulationPtr

from .cache import IntoModulationCache

M = TypeVar("M", bound=ModulationBase)


class Fir(
IntoModulationCache["Fir[M]"],
IntoModulationRadiationPressure["Fir[M]"],
ModulationBase["Fir[M]"],
Generic[M],
):
_m: M
_coef: np.ndarray

def __init__(self: "Fir[M]", m: M, iterable: Iterable[float]) -> None:
self._m = m
self._loop_behavior = m._loop_behavior
self._coef = np.fromiter(iterable, dtype=ctypes.c_float)

def _modulation_ptr(self: "Fir[M]") -> ModulationPtr:
return Base().modulation_with_fir(
self._m._modulation_ptr(),
self._loop_behavior,
self._coef.ctypes.data_as(ctypes.POINTER(ctypes.c_float)), # type: ignore[arg-type]
len(self._coef),
)


class IntoModulationFir(ModulationBase[M], Generic[M]):
def with_fir(self: M, iterable: Iterable[float]) -> "Fir[M]":
return Fir(self, iterable)
2 changes: 2 additions & 0 deletions pyautd3/driver/datagram/modulation/modulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from pyautd3.driver.datagram.modulation.base import ModulationBase
from pyautd3.driver.datagram.modulation.cache import IntoModulationCache
from pyautd3.driver.datagram.modulation.fir import IntoModulationFir
from pyautd3.driver.datagram.modulation.radiation_pressure import IntoModulationRadiationPressure
from pyautd3.driver.defined.freq import Freq
from pyautd3.driver.firmware.fpga.sampling_config import SamplingConfig
Expand All @@ -16,6 +17,7 @@
class Modulation(
IntoModulationCache[M],
IntoModulationRadiationPressure[M],
IntoModulationFir[M],
ModulationBase[M],
Generic[M],
metaclass=ABCMeta,
Expand Down
39 changes: 39 additions & 0 deletions pyautd3/driver/datagram/phase_corr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import ctypes
import threading
from collections.abc import Callable

from pyautd3.driver.datagram.with_parallel_threshold import IntoDatagramWithParallelThreshold
from pyautd3.driver.datagram.with_timeout import IntoDatagramWithTimeout
from pyautd3.driver.firmware.fpga.phase import Phase
from pyautd3.driver.geometry import Geometry
from pyautd3.driver.geometry.device import Device
from pyautd3.driver.geometry.transducer import Transducer
from pyautd3.native_methods.autd3capi import NativeMethods as Base
from pyautd3.native_methods.autd3capi_driver import DatagramPtr, GeometryPtr

from .datagram import Datagram


class PhaseCorrection(
IntoDatagramWithTimeout["PhaseCorrection"],
IntoDatagramWithParallelThreshold["PhaseCorrection"],
Datagram,
):
_cache: dict[int, Callable[[Transducer], Phase]]
_lock: threading.Lock

def __init__(self: "PhaseCorrection", f: Callable[[Device], Callable[[Transducer], Phase]]) -> None:
super().__init__()
self._cache = {}
self._lock = threading.Lock()

def f_native(_context: ctypes.c_void_p, geometry_ptr: GeometryPtr, dev_idx: int, tr_idx: int) -> int:
if dev_idx not in self._cache:
with self._lock:
self._cache[dev_idx] = f(Device(dev_idx, geometry_ptr))
return self._cache[dev_idx](Transducer(tr_idx, Base().device(geometry_ptr, dev_idx))).value

self._f_native = ctypes.CFUNCTYPE(ctypes.c_uint8, ctypes.c_void_p, GeometryPtr, ctypes.c_uint16, ctypes.c_uint8)(f_native)

def _datagram_ptr(self: "PhaseCorrection", geometry: Geometry) -> DatagramPtr:
return Base().datagram_phase_corr(self._f_native, None, geometry._ptr) # type: ignore[arg-type]
Loading

0 comments on commit a38e664

Please sign in to comment.