Skip to content

Commit

Permalink
Added FPS counter and "infinite" FPS mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Lesches committed Jul 28, 2023
1 parent 0da24f5 commit 254d8b8
Showing 1 changed file with 36 additions and 11 deletions.
47 changes: 36 additions & 11 deletions lib/src/camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,46 @@ 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
late final Camera camera;
Camera camera;
/// Holds the current details of the camera
late final CameraDetails details;
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){
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));
return;
}
timer = Timer.periodic(Duration(milliseconds: 1000 ~/ details.fps), (runner) {
sendFrame();
});
}

/// disposes of the camera and the timer
Expand All @@ -36,21 +55,27 @@ class CameraManager {
///
/// reset the timer for FPS if needed, change resolution, enable or disable
void updateDetails({required CameraDetails details}){
details.mergeFromMessage(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
final frame = camera.getJpg();
if(frame == null){
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;
}
}

0 comments on commit 254d8b8

Please sign in to comment.