From 91419e92cffe7f1c522bbf8e95c37f986b4235ab Mon Sep 17 00:00:00 2001 From: Gold87 <91761103+Gold872@users.noreply.github.com> Date: Wed, 13 Aug 2025 17:57:38 -0400 Subject: [PATCH] Reformat all files --- bin/lidar.dart | 40 ++-- lib/src/collection.dart | 10 +- .../generated/librealsense_ffi_bindings.dart | 211 +++++++++--------- lib/src/isolates/child.dart | 73 +++--- lib/src/isolates/opencv.dart | 38 +++- lib/src/isolates/parent.dart | 76 ++++--- lib/src/isolates/payload.dart | 11 +- lib/src/isolates/realsense.dart | 10 +- lib/src/lidar.dart | 5 +- lib/src/realsense/ffi.dart | 2 +- lib/src/realsense/interface.dart | 9 +- lib/src/realsense/realsense_ffi.dart | 19 +- lib/src/realsense/realsense_stub.dart | 25 ++- lib/src/utils/opencv.dart | 14 +- 14 files changed, 317 insertions(+), 226 deletions(-) diff --git a/bin/lidar.dart b/bin/lidar.dart index deb685e..d12bc5f 100644 --- a/bin/lidar.dart +++ b/bin/lidar.dart @@ -6,27 +6,27 @@ import "dart:typed_data"; import "package:burt_network/udp.dart"; void main() async { - final socket = UdpSocket(port: 8004); - await socket.init(); - socket.stream.listen(temp); - while (true) { - await Future.delayed(const Duration(seconds: 1)); - } + final socket = UdpSocket(port: 8004); + await socket.init(); + socket.stream.listen(temp); + while (true) { + await Future.delayed(const Duration(seconds: 1)); + } } void temp(Datagram packet) { - final data = Float64List.sublistView(packet.data); - final processed = [ - for (final number in data) - //if (!number.isNaN) - number.toStringAsFixed(3), - ]; - print("------------------------------------------"); - if(processed.length == 271){ - print("Angle Data"); - } else if(processed.length == 542){ - //return; - print("Coordinate Data"); - } - print(processed); + final data = Float64List.sublistView(packet.data); + final processed = [ + for (final number in data) + //if (!number.isNaN) + number.toStringAsFixed(3), + ]; + print("------------------------------------------"); + if (processed.length == 271) { + print("Angle Data"); + } else if (processed.length == 542) { + //return; + print("Coordinate Data"); + } + print(processed); } diff --git a/lib/src/collection.dart b/lib/src/collection.dart index de48de3..a28cd75 100644 --- a/lib/src/collection.dart +++ b/lib/src/collection.dart @@ -8,7 +8,11 @@ import "package:video/video.dart"; /// Class to contain all video devices class Collection extends Service { /// The [RoverSocket] to send messages through - late final videoServer = RoverSocket(port: 8002, device: Device.VIDEO, collection: this); + late final videoServer = RoverSocket( + port: 8002, + device: Device.VIDEO, + collection: this, + ); /// Main parent isolate final cameras = CameraManager(); @@ -19,7 +23,9 @@ class Collection extends Service { /// Function to initialize cameras @override Future init() async { - logger..trace("Running in trace mode")..debug("Running in debug mode"); + logger + ..trace("Running in trace mode") + ..debug("Running in debug mode"); await cameras.init(); await lidar.init(); await videoServer.init(); diff --git a/lib/src/generated/librealsense_ffi_bindings.dart b/lib/src/generated/librealsense_ffi_bindings.dart index 7434ba9..5e4810d 100644 --- a/lib/src/generated/librealsense_ffi_bindings.dart +++ b/lib/src/generated/librealsense_ffi_bindings.dart @@ -12,17 +12,16 @@ import 'package:ffi/ffi.dart' as pkg_ffi; class LibRealSenseBindings { /// Holds the symbol lookup function. final ffi.Pointer Function(String symbolName) - _lookup; + _lookup; /// The symbols are looked up in [dynamicLibrary]. LibRealSenseBindings(ffi.DynamicLibrary dynamicLibrary) - : _lookup = dynamicLibrary.lookup; + : _lookup = dynamicLibrary.lookup; /// The symbols are looked up with [lookup]. LibRealSenseBindings.fromLookup( - ffi.Pointer Function(String symbolName) - lookup) - : _lookup = lookup; + ffi.Pointer Function(String symbolName) lookup, + ) : _lookup = lookup; /// Initialization ffi.Pointer RealSense_create() { @@ -31,128 +30,130 @@ class LibRealSenseBindings { late final _RealSense_createPtr = _lookup Function()>>( - 'RealSense_create'); - late final _RealSense_create = _RealSense_createPtr.asFunction< - ffi.Pointer Function()>(); - - void RealSense_free( - ffi.Pointer ptr, - ) { - return _RealSense_free( - ptr, - ); + 'RealSense_create', + ); + late final _RealSense_create = + _RealSense_createPtr.asFunction< + ffi.Pointer Function() + >(); + + void RealSense_free(ffi.Pointer ptr) { + return _RealSense_free(ptr); } - late final _RealSense_freePtr = _lookup< - ffi.NativeFunction)>>( - 'RealSense_free'); - late final _RealSense_free = _RealSense_freePtr.asFunction< - void Function(ffi.Pointer)>(); - - BurtRsStatus RealSense_init( - ffi.Pointer ptr, - ) { - return BurtRsStatus.fromValue(_RealSense_init( - ptr, - )); + late final _RealSense_freePtr = + _lookup< + ffi.NativeFunction)> + >('RealSense_free'); + late final _RealSense_free = + _RealSense_freePtr.asFunction< + void Function(ffi.Pointer) + >(); + + BurtRsStatus RealSense_init(ffi.Pointer ptr) { + return BurtRsStatus.fromValue(_RealSense_init(ptr)); } - late final _RealSense_initPtr = _lookup< - ffi.NativeFunction< - ffi.UnsignedInt Function( - ffi.Pointer)>>('RealSense_init'); - late final _RealSense_init = _RealSense_initPtr.asFunction< - int Function(ffi.Pointer)>(); + late final _RealSense_initPtr = + _lookup< + ffi.NativeFunction< + ffi.UnsignedInt Function(ffi.Pointer) + > + >('RealSense_init'); + late final _RealSense_init = + _RealSense_initPtr.asFunction< + int Function(ffi.Pointer) + >(); ffi.Pointer RealSense_getDeviceName( ffi.Pointer ptr, ) { - return _RealSense_getDeviceName( - ptr, - ); + return _RealSense_getDeviceName(ptr); } - late final _RealSense_getDeviceNamePtr = _lookup< - ffi.NativeFunction< - ffi.Pointer Function( - ffi.Pointer)>>('RealSense_getDeviceName'); - late final _RealSense_getDeviceName = _RealSense_getDeviceNamePtr.asFunction< - ffi.Pointer Function(ffi.Pointer)>(); - - BurtRsConfig RealSense_getDeviceConfig( - ffi.Pointer ptr, - ) { - return _RealSense_getDeviceConfig( - ptr, - ); + late final _RealSense_getDeviceNamePtr = + _lookup< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer) + > + >('RealSense_getDeviceName'); + late final _RealSense_getDeviceName = + _RealSense_getDeviceNamePtr.asFunction< + ffi.Pointer Function(ffi.Pointer) + >(); + + BurtRsConfig RealSense_getDeviceConfig(ffi.Pointer ptr) { + return _RealSense_getDeviceConfig(ptr); } - late final _RealSense_getDeviceConfigPtr = _lookup< - ffi - .NativeFunction)>>( - 'RealSense_getDeviceConfig'); - late final _RealSense_getDeviceConfig = _RealSense_getDeviceConfigPtr - .asFunction)>(); + late final _RealSense_getDeviceConfigPtr = + _lookup< + ffi.NativeFunction)> + >('RealSense_getDeviceConfig'); + late final _RealSense_getDeviceConfig = + _RealSense_getDeviceConfigPtr.asFunction< + BurtRsConfig Function(ffi.Pointer) + >(); /// Streams - BurtRsStatus RealSense_startStream( - ffi.Pointer ptr, - ) { - return BurtRsStatus.fromValue(_RealSense_startStream( - ptr, - )); + BurtRsStatus RealSense_startStream(ffi.Pointer ptr) { + return BurtRsStatus.fromValue(_RealSense_startStream(ptr)); } - late final _RealSense_startStreamPtr = _lookup< - ffi.NativeFunction< - ffi.UnsignedInt Function( - ffi.Pointer)>>('RealSense_startStream'); - late final _RealSense_startStream = _RealSense_startStreamPtr.asFunction< - int Function(ffi.Pointer)>(); - - void RealSense_stopStream( - ffi.Pointer ptr, - ) { - return _RealSense_stopStream( - ptr, - ); + late final _RealSense_startStreamPtr = + _lookup< + ffi.NativeFunction< + ffi.UnsignedInt Function(ffi.Pointer) + > + >('RealSense_startStream'); + late final _RealSense_startStream = + _RealSense_startStreamPtr.asFunction< + int Function(ffi.Pointer) + >(); + + void RealSense_stopStream(ffi.Pointer ptr) { + return _RealSense_stopStream(ptr); } - late final _RealSense_stopStreamPtr = _lookup< - ffi.NativeFunction)>>( - 'RealSense_stopStream'); - late final _RealSense_stopStream = _RealSense_stopStreamPtr.asFunction< - void Function(ffi.Pointer)>(); + late final _RealSense_stopStreamPtr = + _lookup< + ffi.NativeFunction)> + >('RealSense_stopStream'); + late final _RealSense_stopStream = + _RealSense_stopStreamPtr.asFunction< + void Function(ffi.Pointer) + >(); /// Frames ffi.Pointer RealSense_getDepthFrame( ffi.Pointer ptr, ) { - return _RealSense_getDepthFrame( - ptr, - ); + return _RealSense_getDepthFrame(ptr); } - late final _RealSense_getDepthFramePtr = _lookup< - ffi.NativeFunction< - ffi.Pointer Function( - ffi.Pointer)>>('RealSense_getDepthFrame'); - late final _RealSense_getDepthFrame = _RealSense_getDepthFramePtr.asFunction< - ffi.Pointer Function(ffi.Pointer)>(); - - void NativeFrames_free( - ffi.Pointer ptr, - ) { - return _NativeFrames_free( - ptr, - ); + late final _RealSense_getDepthFramePtr = + _lookup< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer) + > + >('RealSense_getDepthFrame'); + late final _RealSense_getDepthFrame = + _RealSense_getDepthFramePtr.asFunction< + ffi.Pointer Function(ffi.Pointer) + >(); + + void NativeFrames_free(ffi.Pointer ptr) { + return _NativeFrames_free(ptr); } late final _NativeFrames_freePtr = _lookup)>>( - 'NativeFrames_free'); - late final _NativeFrames_free = _NativeFrames_freePtr.asFunction< - void Function(ffi.Pointer)>(); + 'NativeFrames_free', + ); + late final _NativeFrames_free = + _NativeFrames_freePtr.asFunction< + void Function(ffi.Pointer) + >(); } enum BurtRsStatus { @@ -166,13 +167,13 @@ enum BurtRsStatus { const BurtRsStatus(this.value); static BurtRsStatus fromValue(int value) => switch (value) { - 0 => BurtRsStatus_ok, - 1 => BurtRsStatus_no_device, - 2 => BurtRsStatus_too_many_devices, - 3 => BurtRsStatus_resolution_unknown, - 4 => BurtRsStatus_scale_unknown, - _ => throw ArgumentError("Unknown value for BurtRsStatus: $value"), - }; + 0 => BurtRsStatus_ok, + 1 => BurtRsStatus_no_device, + 2 => BurtRsStatus_too_many_devices, + 3 => BurtRsStatus_resolution_unknown, + 4 => BurtRsStatus_scale_unknown, + _ => throw ArgumentError('Unknown value for BurtRsStatus: $value'), + }; } final class BurtRsConfig extends ffi.Struct { diff --git a/lib/src/isolates/child.dart b/lib/src/isolates/child.dart index 7309279..f355fd5 100644 --- a/lib/src/isolates/child.dart +++ b/lib/src/isolates/child.dart @@ -26,16 +26,17 @@ const maxPacketLength = 60000; /// - periodically logging how many frames were successfully read /// - periodically calling [sendFrames] to read the camera /// - calling [updateDetails] when a new [VideoCommand] arrives. -abstract class CameraIsolate extends IsolateChild { +abstract class CameraIsolate + extends IsolateChild { // Jetson has 6 cores, Pi has 4 - static final String _linuxUserHomeFolder = - Platform.numberOfProcessors == 6 ? "/home/rover" : "/home/pi"; + static final String _linuxUserHomeFolder = Platform.numberOfProcessors == 6 + ? "/home/rover" + : "/home/pi"; /// The root directory of the shared network folder - static final String baseDirectory = - Platform.isLinux - ? "$_linuxUserHomeFolder/shared" - : Directory.current.path; + static final String baseDirectory = Platform.isLinux + ? "$_linuxUserHomeFolder/shared" + : Directory.current.path; /// Holds the current details of the camera. final CameraDetails details; @@ -53,10 +54,13 @@ abstract class CameraIsolate extends IsolateChild /// A timer to periodically send the camera status to the dashboard. Timer? statusTimer; + /// A timer to read from the camera at an FPS given by [details]. Timer? frameTimer; + /// A timer to log out the [fpsCount] every 5 seconds using [sendLog]. Timer? fpsTimer; + /// Records how many FPS this camera is actually running at. int fpsCount = 0; @@ -74,13 +78,7 @@ abstract class CameraIsolate extends IsolateChild /// Note: it is important to _not_ log this message directly in _this_ isolate, as it will /// not be configurable by the parent isolate and will not be sent to the Dashboard. void sendLog(LogLevel level, String message, {String? body}) => - sendToParent( - LogPayload( - level: level, - message: message, - body: body, - ), - ); + sendToParent(LogPayload(level: level, message: message, body: body)); @override Future onSpawn() async { @@ -156,10 +154,13 @@ abstract class CameraIsolate extends IsolateChild /// Updates the camera's [details], which will take effect on the next [sendFrame] call. void updateDetails(CameraDetails newDetails, {bool save = true}) { - final shouldRestart = (newDetails.hasFps() && newDetails.fps != details.fps) - || (newDetails.hasResolutionHeight() && newDetails.resolutionHeight != details.resolutionHeight) - || (newDetails.hasResolutionWidth() && newDetails.resolutionWidth != details.resolutionWidth) - || newDetails.status == CameraStatus.CAMERA_DISABLED; + final shouldRestart = + (newDetails.hasFps() && newDetails.fps != details.fps) || + (newDetails.hasResolutionHeight() && + newDetails.resolutionHeight != details.resolutionHeight) || + (newDetails.hasResolutionWidth() && + newDetails.resolutionWidth != details.resolutionWidth) || + newDetails.status == CameraStatus.CAMERA_DISABLED; details.mergeFromMessage(newDetails); if (shouldRestart) { stop(); @@ -181,7 +182,10 @@ abstract class CameraIsolate extends IsolateChild } configFile.writeAsStringSync(jsonEncode(details.toProto3Json())); } catch (e) { - logger.error("Failed to save details to ${configFile.path}", body: e.toString()); + logger.error( + "Failed to save details to ${configFile.path}", + body: e.toString(), + ); } } @@ -202,10 +206,10 @@ abstract class CameraIsolate extends IsolateChild Future sendFrames(); /// Reads a frame and returns the data in jpeg format - /// + /// /// The image this returns is intended to be taken at maximum quality /// and get saved as a screenshot - /// + /// /// Most likely, this image will be too big to send over the network Future getScreenshotJpeg(); @@ -224,12 +228,23 @@ abstract class CameraIsolate extends IsolateChild // from the parent isolate VecUChar.finalizer.detach(image); sendToParent(FramePayload(details: details, address: image.ptr.address)); - } else if (details.quality > 25) { // Frame too large, lower quality - sendLog(LogLevel.debug, "Lowering quality for $name from ${details.quality}"); - details.quality -= 1; // maybe next frame can send - } else { // Frame too large, quality cannot be lowered - sendLog(LogLevel.warning, "Frame from camera $name are too large (${image.length})"); - updateDetails(CameraDetails(status: CameraStatus.FRAME_TOO_LARGE), save: false); + } else if (details.quality > 25) { + // Frame too large, lower quality + sendLog( + LogLevel.debug, + "Lowering quality for $name from ${details.quality}", + ); + details.quality -= 1; // maybe next frame can send + } else { + // Frame too large, quality cannot be lowered + sendLog( + LogLevel.warning, + "Frame from camera $name are too large (${image.length})", + ); + updateDetails( + CameraDetails(status: CameraStatus.FRAME_TOO_LARGE), + save: false, + ); } } @@ -237,7 +252,9 @@ abstract class CameraIsolate extends IsolateChild void start() { if (details.status != CameraStatus.CAMERA_ENABLED) return; sendLog(LogLevel.debug, "Starting camera $name. Status=${details.status}"); - final interval = details.fps == 0 ? Duration.zero : Duration(milliseconds: 1000 ~/ details.fps); + final interval = details.fps == 0 + ? Duration.zero + : Duration(milliseconds: 1000 ~/ details.fps); frameTimer = Timer.periodic(interval, _frameCallback); fpsTimer = Timer.periodic(const Duration(seconds: 5), (_) { sendLog(LogLevel.trace, "Camera $name sent ${fpsCount ~/ 5} frames"); diff --git a/lib/src/isolates/opencv.dart b/lib/src/isolates/opencv.dart index a40e46b..6a68375 100644 --- a/lib/src/isolates/opencv.dart +++ b/lib/src/isolates/opencv.dart @@ -16,7 +16,10 @@ class OpenCVCameraIsolate extends CameraIsolate { void initCamera() { camera = getCamera(name); camera!.set(CAP_PROP_FOURCC, VideoCapture.toCodec("MJPG")); - camera?.setResolution(width: details.resolutionWidth, height: details.resolutionHeight); + camera?.setResolution( + width: details.resolutionWidth, + height: details.resolutionHeight, + ); frameProperties = FrameProperties.fromFrameDetails( captureWidth: camera!.width, captureHeight: camera!.height, @@ -29,7 +32,10 @@ class OpenCVCameraIsolate extends CameraIsolate { if (!camera!.isOpened) { sendLog(LogLevel.warning, "Camera $name is not connected"); - updateDetails(CameraDetails(status: CameraStatus.CAMERA_DISCONNECTED), save: false); + updateDetails( + CameraDetails(status: CameraStatus.CAMERA_DISCONNECTED), + save: false, + ); stop(); } } @@ -44,9 +50,14 @@ class OpenCVCameraIsolate extends CameraIsolate { void updateDetails(CameraDetails newDetails, {bool save = true}) { super.updateDetails(newDetails, save: save); if (details.status != CameraStatus.CAMERA_ENABLED || camera == null) return; - if ((details.hasResolutionWidth() && details.resolutionWidth != camera!.width) || - details.hasResolutionHeight() && details.resolutionHeight != camera!.height) { - camera?.setResolution(width: details.resolutionWidth, height: details.resolutionHeight); + if ((details.hasResolutionWidth() && + details.resolutionWidth != camera!.width) || + details.hasResolutionHeight() && + details.resolutionHeight != camera!.height) { + camera?.setResolution( + width: details.resolutionWidth, + height: details.resolutionHeight, + ); } if (details.hasZoom() && details.zoom != camera!.zoom) { camera!.zoom = details.zoom; @@ -64,7 +75,8 @@ class OpenCVCameraIsolate extends CameraIsolate { camera!.autofocus = details.autofocus; } if (frameProperties == null || - (newDetails.hasDiagonalFov() && newDetails.diagonalFov != frameProperties!.diagonalFoV) || + (newDetails.hasDiagonalFov() && + newDetails.diagonalFov != frameProperties!.diagonalFoV) || frameProperties!.captureWidth != camera!.width || frameProperties!.captureHeight != camera!.height) { frameProperties = FrameProperties.fromFrameDetails( @@ -118,7 +130,9 @@ class OpenCVCameraIsolate extends CameraIsolate { } if (details.streamWidth != streamWidth || details.streamHeight != streamHeight) { - updateDetails(CameraDetails(streamWidth: streamWidth, streamHeight: streamHeight)); + updateDetails( + CameraDetails(streamWidth: streamWidth, streamHeight: streamHeight), + ); } VecUChar? frame; @@ -150,9 +164,13 @@ class OpenCVCameraIsolate extends CameraIsolate { } matrix.dispose(); - if (frame == null) { // Error getting the frame + if (frame == null) { + // Error getting the frame sendLog(LogLevel.warning, "Camera $name didn't respond"); - updateDetails(CameraDetails(status: CameraStatus.CAMERA_NOT_RESPONDING), save: false); + updateDetails( + CameraDetails(status: CameraStatus.CAMERA_NOT_RESPONDING), + save: false, + ); return; } @@ -190,7 +208,7 @@ class OpenCVCameraIsolate extends CameraIsolate { } final (success, matrix) = await camera!.readAsync(); - + camera!.dispose(); camera = getCamera(name); diff --git a/lib/src/isolates/parent.dart b/lib/src/isolates/parent.dart index 073ff7c..5fd7573 100644 --- a/lib/src/isolates/parent.dart +++ b/lib/src/isolates/parent.dart @@ -7,7 +7,10 @@ import "package:burt_network/burt_network.dart"; import "package:video/video.dart"; /// The socket to send autonomy data to. -final autonomySocket = SocketInfo(address: InternetAddress("192.168.1.30"), port: 8003); +final autonomySocket = SocketInfo( + address: InternetAddress("192.168.1.30"), + port: 8003, +); /// The socket to send frames that need to be analyzed to. final cvSocket = SocketInfo(address: InternetAddress.loopbackIPv4, port: 8006); @@ -52,7 +55,7 @@ class CameraManager extends Service { final isolate = RealSenseIsolate(details: details); await parent.spawn(isolate); // All other cameras share the same logic, even future cameras - default: // ignore: no_default_cases + default: // ignore: no_default_cases final details = loadCameraDetails(getDefaultDetails(name), name); final isolate = OpenCVCameraIsolate(details: details); await parent.spawn(isolate); @@ -97,10 +100,7 @@ class CameraManager extends Service { // The vision program will detect objects and send metadata to Autonomy. // The frames will be annotated and sent back here. See [_handleVision]. collection.videoServer.sendMessage( - VideoData( - frame: image, - details: details, - ), + VideoData(frame: image, details: details), destination: cvSocket, ); } else { @@ -113,26 +113,41 @@ class CameraManager extends Service { ); } case DepthFramePayload(): - collection.videoServer.sendMessage(VideoData(frame: data.frame.depthFrame), destination: autonomySocket); + collection.videoServer.sendMessage( + VideoData(frame: data.frame.depthFrame), + destination: autonomySocket, + ); data.dispose(); - case LogPayload(): switch (data.level) { - // Turns out using deprecated members when you *have* to still results in a lint. - // See https://github.com/dart-lang/linter/issues/4852 for why we ignore it. - case LogLevel.all: logger.info(data.message, body: data.body); - // ignore: deprecated_member_use - case LogLevel.verbose: logger.trace(data.message, body: data.body); - case LogLevel.trace: logger.trace(data.message, body: data.body); - case LogLevel.debug: logger.debug(data.message, body: data.body); - case LogLevel.info: logger.info(data.message, body: data.body); - case LogLevel.warning: logger.warning(data.message, body: data.body); - case LogLevel.error: logger.error(data.message, body: data.body); - // ignore: deprecated_member_use - case LogLevel.wtf: logger.info(data.message, body: data.body); - case LogLevel.fatal: logger.critical(data.message, body: data.body); - // ignore: deprecated_member_use - case LogLevel.nothing: logger.info(data.message, body: data.body); - case LogLevel.off: logger.info(data.message, body: data.body); - } + case LogPayload(): + switch (data.level) { + // Turns out using deprecated members when you *have* to still results in a lint. + // See https://github.com/dart-lang/linter/issues/4852 for why we ignore it. + case LogLevel.all: + logger.info(data.message, body: data.body); + // ignore: deprecated_member_use + case LogLevel.verbose: + logger.trace(data.message, body: data.body); + case LogLevel.trace: + logger.trace(data.message, body: data.body); + case LogLevel.debug: + logger.debug(data.message, body: data.body); + case LogLevel.info: + logger.info(data.message, body: data.body); + case LogLevel.warning: + logger.warning(data.message, body: data.body); + case LogLevel.error: + logger.error(data.message, body: data.body); + // ignore: deprecated_member_use + case LogLevel.wtf: + logger.info(data.message, body: data.body); + case LogLevel.fatal: + logger.critical(data.message, body: data.body); + // ignore: deprecated_member_use + case LogLevel.nothing: + logger.info(data.message, body: data.body); + case LogLevel.off: + logger.info(data.message, body: data.body); + } case ObjectDetectionPayload(:final details, :final tags): final visionResult = VideoData( details: details, @@ -140,13 +155,16 @@ class CameraManager extends Service { version: Version(major: 1, minor: 2), ); collection.videoServer.sendMessage(visionResult); - collection.videoServer.sendMessage(visionResult, destination: autonomySocket); + collection.videoServer.sendMessage( + visionResult, + destination: autonomySocket, + ); } } /// Forwards the command to the appropriate camera. void _handleCommand(VideoCommand command) { - collection.videoServer.sendMessage(command); // echo the request + collection.videoServer.sendMessage(command); // echo the request var cameraName = command.details.name; if (cameraName == CameraName.ROVER_FRONT) { cameraName = CameraName.AUTONOMY_DEPTH; @@ -166,7 +184,9 @@ class CameraManager extends Service { /// Stops all the cameras managed by this class. void stopAll() { - final command = VideoCommand(details: CameraDetails(status: CameraStatus.CAMERA_DISABLED)); + final command = VideoCommand( + details: CameraDetails(status: CameraStatus.CAMERA_DISABLED), + ); for (final name in CameraName.values) { if (name == CameraName.CAMERA_NAME_UNDEFINED || name == CameraName.ROVER_FRONT) { diff --git a/lib/src/isolates/payload.dart b/lib/src/isolates/payload.dart index 39db960..19276c6 100644 --- a/lib/src/isolates/payload.dart +++ b/lib/src/isolates/payload.dart @@ -9,7 +9,9 @@ import "package:video/video.dart"; /// Instead of having nullable fields on this class, we subclass it and provide /// only the relevant fields for each subclass. That way, for example, you cannot /// accidentally send a frame without a [CameraDetails]. -sealed class IsolatePayload { const IsolatePayload(); } +sealed class IsolatePayload { + const IsolatePayload(); +} /// A container for a pointer to a native buffer that can be sent across isolates. /// @@ -46,10 +48,13 @@ class FramePayload extends IsolatePayload { class LogPayload extends IsolatePayload { /// The level to log this message. final LogLevel level; + /// The message to log. final String message; + /// The body of the message final String? body; + /// A const constructor. const LogPayload({required this.level, required this.message, this.body}); } @@ -58,9 +63,9 @@ class LogPayload extends IsolatePayload { class DepthFramePayload extends IsolatePayload { /// The address of the data in memory, since pointers cannot be sent across isolates. final int address; + /// Saves the address of the pointer to send across isolates. - DepthFramePayload(Pointer pointer) : - address = pointer.address; + DepthFramePayload(Pointer pointer) : address = pointer.address; /// The native frame being referenced by this pointer. Pointer get frame => Pointer.fromAddress(address); diff --git a/lib/src/isolates/realsense.dart b/lib/src/isolates/realsense.dart index 424ad4e..4d36a9d 100644 --- a/lib/src/isolates/realsense.dart +++ b/lib/src/isolates/realsense.dart @@ -32,6 +32,7 @@ extension on CameraDetails { class RealSenseIsolate extends CameraIsolate { /// The native RealSense object. MUST be `late` so it isn't initialized on the parent isolate. late final RealSenseInterface camera = RealSenseInterface.forPlatform(); + /// Creates an isolate to read from the RealSense camera. RealSenseIsolate({required super.details}); @@ -118,7 +119,10 @@ class RealSenseIsolate extends CameraIsolate { // Compress colorized frame final Pointer rawColorized = frames.ref.colorized_data; if (rawColorized == nullptr) return null; - final colorizedMatrix = rawColorized.toOpenCVMat(camera.depthResolution, length: frames.ref.colorized_length); + final colorizedMatrix = rawColorized.toOpenCVMat( + camera.depthResolution, + length: frames.ref.colorized_length, + ); final colorizedJpg = colorizedMatrix.encodeJpg(quality: details.quality); colorizedMatrix.dispose(); @@ -172,7 +176,9 @@ class RealSenseIsolate extends CameraIsolate { } if (details.streamWidth != streamWidth || details.streamHeight != streamHeight) { - updateDetails(CameraDetails(streamWidth: streamWidth, streamHeight: streamHeight)); + updateDetails( + CameraDetails(streamWidth: streamWidth, streamHeight: streamHeight), + ); } VecUChar? frame; diff --git a/lib/src/lidar.dart b/lib/src/lidar.dart index 28a4269..be98564 100644 --- a/lib/src/lidar.dart +++ b/lib/src/lidar.dart @@ -48,10 +48,7 @@ class LidarManager extends Service { List _processCartesianPoints(List data) => [ for (int i = 0; i < data.length - 1; i += 2) - LidarCartesianPoint( - x: data[i], - y: data[i + 1], - ), + LidarCartesianPoint(x: data[i], y: data[i + 1]), ]; List _processPolarPoints(List data) => [ diff --git a/lib/src/realsense/ffi.dart b/lib/src/realsense/ffi.dart index 3c98d1f..43a9ec0 100644 --- a/lib/src/realsense/ffi.dart +++ b/lib/src/realsense/ffi.dart @@ -11,7 +11,7 @@ extension NativeFramesUtils on Pointer { void dispose() => realsenseLib.NativeFrames_free(this); /// The depth frame, as raw bytes. - /// + /// /// NOTE: The RealSense SDK returns [Uint16]s, but this is cast to a [Uint8] for UDP transfer. Be /// sure to re-cast it on the processing side! Uint8List get depthFrame { diff --git a/lib/src/realsense/interface.dart b/lib/src/realsense/interface.dart index 46e2959..567d3c8 100644 --- a/lib/src/realsense/interface.dart +++ b/lib/src/realsense/interface.dart @@ -13,28 +13,35 @@ typedef Resolution = ({int width, int height}); abstract class RealSenseInterface { /// A const constructor. const RealSenseInterface(); + /// Decides which implementation to use depending on platform. - factory RealSenseInterface.forPlatform() => Platform.isLinux ? RealSenseFFI() : RealSenseStub(); + factory RealSenseInterface.forPlatform() => + Platform.isLinux ? RealSenseFFI() : RealSenseStub(); /// Initializes the RealSense. Returns whether the initialization was successful. bool init(); + /// Releases the RealSense. Calling [init] again should re-open the device. void dispose(); /// Starts the RealSense stream and waits for a valid frame. bool startStream(); + /// Stops the stream but keeps the device alive. void stopStream(); /// The resolution of the depth frames. Resolution get depthResolution; + /// The resolution of the RGB frames. Resolution get rgbResolution; + /// The depth scale -- each pixel in the depth frame is an integer multiple of this, in meters. double get scale; /// Gets the name and model of the camera. String getName(); + /// Gets the currently available frames. May return [nullptr]. Pointer getFrames(); diff --git a/lib/src/realsense/realsense_ffi.dart b/lib/src/realsense/realsense_ffi.dart index 1d8b9a7..889b989 100644 --- a/lib/src/realsense/realsense_ffi.dart +++ b/lib/src/realsense/realsense_ffi.dart @@ -5,12 +5,15 @@ import "package:video/video.dart"; /// An FFI implementation of [RealSenseInterface] using [librealsense](https://github.com/IntelRealSense/librealsense). class RealSenseFFI extends RealSenseInterface { - /// The native FFI device. + /// The native FFI device. final device = realsenseLib.RealSense_create(); - @override late double scale; - @override Resolution depthResolution = (height: 0, width: 0); - @override Resolution rgbResolution = (height: 0, width: 0); - + @override + late double scale; + @override + Resolution depthResolution = (height: 0, width: 0); + @override + Resolution rgbResolution = (height: 0, width: 0); + @override bool init() { final status = realsenseLib.RealSense_init(device); @@ -18,7 +21,8 @@ class RealSenseFFI extends RealSenseInterface { } @override - String getName() => realsenseLib.RealSense_getDeviceName(device).toDartString(); + String getName() => + realsenseLib.RealSense_getDeviceName(device).toDartString(); @override bool startStream() { @@ -42,5 +46,6 @@ class RealSenseFFI extends RealSenseInterface { } @override - Pointer getFrames() => realsenseLib.RealSense_getDepthFrame(device); + Pointer getFrames() => + realsenseLib.RealSense_getDepthFrame(device); } diff --git a/lib/src/realsense/realsense_stub.dart b/lib/src/realsense/realsense_stub.dart index bfd8663..f5da352 100644 --- a/lib/src/realsense/realsense_stub.dart +++ b/lib/src/realsense/realsense_stub.dart @@ -7,16 +7,23 @@ class RealSenseStub extends RealSenseInterface { @override bool init() => false; - @override void dispose() { } - - @override bool startStream() => true; - @override void stopStream() { } + @override + void dispose() {} - @override Resolution get depthResolution => (height: 0, width: 0); - @override Resolution get rgbResolution => (height: 0, width: 0); - @override double get scale => 0; + @override + bool startStream() => true; + @override + void stopStream() {} + @override + Resolution get depthResolution => (height: 0, width: 0); + @override + Resolution get rgbResolution => (height: 0, width: 0); + @override + double get scale => 0; - @override String getName() => "Virtual RealSense"; - @override Pointer getFrames() => nullptr; + @override + String getName() => "Virtual RealSense"; + @override + Pointer getFrames() => nullptr; } diff --git a/lib/src/utils/opencv.dart b/lib/src/utils/opencv.dart index 013e9eb..52b4355 100644 --- a/lib/src/utils/opencv.dart +++ b/lib/src/utils/opencv.dart @@ -67,12 +67,9 @@ extension MatrixUtils on Mat { } /// Draws a crosshair on the image - Future drawCrosshair({ - Point? center, - int thickness = 2, - }) async { + Future drawCrosshair({Point? center, int thickness = 2}) async { center ??= Point(width ~/ 2, height ~/ 2); - + // Vertical segment await lineAsync( this, @@ -111,6 +108,11 @@ extension Uint8ToMat on Pointer { /// Reads this 1-dimensional list as an OpenCV image. Mat toOpenCVMat(Resolution resolution, {int? length}) { length ??= resolution.width * resolution.height; - return Mat.fromList(resolution.height, resolution.width, MatType.CV_8UC3, asTypedList(length)); + return Mat.fromList( + resolution.height, + resolution.width, + MatType.CV_8UC3, + asTypedList(length), + ); } }