Skip to content

Commit

Permalink
Aidan (#1)
Browse files Browse the repository at this point in the history
* not much added

* progress?

* latest

* maybe this will work??

* Re-enable documentation rule

* made requested changes

* onto to big and better things

* Upgraded opencv_ffi

* Added FPS counter and "infinite" FPS mode

* Fixed some bugs

* Removed unused bin files

---------

Co-authored-by: Levi Lesches <[email protected]>
  • Loading branch information
aidanahram and Levi-Lesches authored Jul 28, 2023
1 parent d885c21 commit d10e787
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 35 deletions.
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ linter:
omit_local_variable_types: false # it can be helpful sometimes to annotate types

# Temporarily disabled until we are ready to document
public_member_api_docs: false
# public_member_api_docs: false
23 changes: 0 additions & 23 deletions bin/camera.dart

This file was deleted.

6 changes: 3 additions & 3 deletions bin/video.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: avoid_print
import "package:video/src/collection.dart";

void main() {
print("The main program has not yet been implemented");
void main() async{
await collection.init();
}
81 changes: 81 additions & 0 deletions lib/src/camera.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import "package:burt_network/burt_network.dart";
import "package:opencv_ffi/opencv_ffi.dart";
import "dart:async";
import "collection.dart";

/// Prints the actual FPS of this camera at the debug [LogLevel].
const bool countFps = false;

/// Class to manage [Camera] objects
class CameraManager {
/// Camera that is being controlled
Camera camera;
/// Holds the current details of the camera
CameraDetails details;
/// Timer that is run constantly to send frames
Timer? timer;
bool _isLoading = false;

/// Records how many FPS this camera is actually running at. Enable [countFps] to see it in the logs.
int fpsCount = 0;

/// Constructor
CameraManager({required this.camera, required this.details});

/// The name of this camera (where it is on the rover).
CameraName get name => details.name;

/// Starts the camera and FPS timers.
void startTimer() {
final delay = details.fps == 0 ? Duration.zero : Duration(milliseconds: 1000 ~/ details.fps);
logger.verbose("Waiting for delay: $delay");
timer?.cancel();
timer = Timer.periodic(delay, sendFrame);
if (countFps) Timer.periodic(const Duration(seconds: 5), (_) {logger.debug("Sent ${fpsCount ~/ 5} frames"); fpsCount = 0;});
}

/// Initializes the timer
Future<void> init() async{
if (camera.isOpened){
logger.verbose("Initializing camera: ${details.name}");
startTimer();
} else {
logger.verbose("Camera $name is not connected");
details.mergeFromMessage(CameraDetails(status: CameraStatus.CAMERA_DISCONNECTED));
}
}

/// disposes of the camera and the timer
void dispose(){
camera.dispose();
timer?.cancel();
}

/// Updates the current details
///
/// reset the timer for FPS if needed, change resolution, enable or disable
void updateDetails({required CameraDetails details}){
this.details = details;
startTimer();
}

/// Sends frame to dashboard
///
/// If the camera was connected and then returns a null frame then its status changes to [CameraStatus.CAMERA_NOT_RESPONDING]
void sendFrame(_) { // run this with the timer. Read frame, send to dashboard, handle errors
if (_isLoading) return;
if (countFps) fpsCount++;
_isLoading = true;
final frame = camera.getJpg(quality: details.quality);
collection.videoServer.sendMessage(VideoData(details: details));
if (frame == null) {
updateDetails(details: CameraDetails(status: CameraStatus.CAMERA_NOT_RESPONDING));
collection.videoServer.sendMessage(VideoData(details: details));
timer?.cancel();
} else {
collection.videoServer.sendMessage(VideoData(frame: frame.data, details: CameraDetails(name: CameraName.ROVER_FRONT, status: CameraStatus.CAMERA_ENABLED)));
frame.dispose();
}
_isLoading = false;
}
}
58 changes: 58 additions & 0 deletions lib/src/collection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import "dart:io";
import "dart:async";
import "package:burt_network/burt_network.dart";
import "package:opencv_ffi/opencv_ffi.dart";
import "udp.dart";
import "constants.dart";
import "camera.dart";

/// Default details for a camera
///
/// Used when first creating the camera objects
CameraDetails getDefaultDetails(CameraName name) => CameraDetails(
name: name,
resolutionWidth: 300,
resolutionHeight: 300,
quality: 50,
fps: 24,
status:
CameraStatus.CAMERA_ENABLED,
);

/// Returns the camera depending on device program is running
///
/// Uses [cameraNames] or [cameraIndexes]
Camera getCamera(CameraName name) => Platform.isWindows
? Camera.fromIndex(cameraIndexes[name]!)
: Camera.fromName(cameraNames[name]!);

/// Class to cotain all video devices
class VideoCollection{
/// Holds a list of available cameras
Map<CameraName, CameraManager> cameras = {
for (final name in CameraName.values)
if (name != CameraName.CAMERA_NAME_UNDEFINED)
name: CameraManager(
camera: getCamera(name),
details: getDefaultDetails(name),
)
};

/// [VideoServer] to send messages through
///
/// Defaualt port is 8002 for video
final videoServer = VideoServer(port: 8002);

/// Function to initiliaze cameras
Future<void> init() async{
BurtLogger.level = LogLevel.debug;
await videoServer.init();
for (final camera in cameras.values) {
await camera.init();
}
logger.info("Video program initialized");
}
}

/// Holds all the devices connected
final collection = VideoCollection();
25 changes: 25 additions & 0 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import "package:burt_network/burt_network.dart";

/// These list maps OpenCV IDs (index) to [CameraName]s.
///
/// This is HIGHLY dependent on the EXACT order of the USB ports.
///
/// Map for MAC or LINUX devices
Map<CameraName, String> cameraNames = {
CameraName.ROVER_FRONT: "/dev/realsense_rgb",
CameraName.ROVER_REAR: "...",
CameraName.AUTONOMY_DEPTH: "/dev/realsense_depth",
CameraName.SUBSYSTEM1: "/dev/subsystem1",
CameraName.SUBSYSTEM2: "/dev/subsystem2",
CameraName.SUBSYSTEM3: "/dev/subsystem3",
};

/// Map for WINDOWS devices
Map<CameraName, int> cameraIndexes = {
CameraName.ROVER_FRONT: 0,
CameraName.ROVER_REAR: 1,
CameraName.AUTONOMY_DEPTH: 1,
CameraName.SUBSYSTEM1: 2,
CameraName.SUBSYSTEM2: 3,
CameraName.SUBSYSTEM3: 4,
};
21 changes: 21 additions & 0 deletions lib/src/udp.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import "package:burt_network/burt_network.dart";
import "collection.dart";

/// Class for the video program to interact with the dashboard
class VideoServer extends ServerSocket{
/// Requires a port to communicate through
VideoServer({required super.port}) : super(device: Device.VIDEO);

@override
void onMessage(WrappedMessage wrapper) {
// ignore message if not a video message
if(wrapper.name != VideoCommand().messageName) return;
final command = VideoCommand.fromBuffer(wrapper.data);
// Return the message to tell dashboard the message was received
sendMessage(command);
// Send LOADING before making any changes
sendMessage(VideoData(id: command.id, details: CameraDetails(status: CameraStatus.CAMERA_LOADING)));
// Change the settings
collection.cameras[command.details.name]!.updateDetails(details: command.details);
}
}
2 changes: 2 additions & 0 deletions lib/video.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export "src/collection.dart";
export "src/udp.dart";
Binary file modified opencv_ffi.dll
Binary file not shown.
14 changes: 7 additions & 7 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ packages:
description:
path: "."
ref: HEAD
resolved-ref: e703af76131876b8c8d34a8a6c1d1177f6b13461
resolved-ref: "4bbf14671d0bc2ed180bae246904df52c8f092b3"
url: "https://github.com/BinghamtonRover/Dart-Networking"
source: git
version: "1.0.0"
collection:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -86,10 +86,10 @@ packages:
dependency: transitive
description:
name: dart_internal
sha256: dae3976f383beddcfcd07ad5291a422df2c8c0a8a03c52cda63ac7b4f26e0f4e
sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567"
url: "https://pub.dev"
source: hosted
version: "0.2.8"
version: "0.2.9"
ffi:
dependency: transitive
description:
Expand Down Expand Up @@ -215,7 +215,7 @@ packages:
description:
path: "."
ref: HEAD
resolved-ref: "9bf9db4a2a3a0bbfb844ae2b389c322b5e89c4b5"
resolved-ref: "118f073e4502ad38273e6c875bcd3e32dc0a4306"
url: "https://github.com/BinghamtonRover/OpenCV-FFI"
source: git
version: "1.0.0"
Expand Down Expand Up @@ -428,4 +428,4 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.0.5 <3.2.0"
dart: ">=3.0.0 <3.3.0"
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version: 1.0.0
publish_to: none

environment:
sdk: ^3.0.5
sdk: ^3.0.0

# Add regular dependencies here.
dependencies:
Expand Down

0 comments on commit d10e787

Please sign in to comment.