diff --git a/configs/config.json b/configs/config.json index 9877dafc..6c25ad69 100644 --- a/configs/config.json +++ b/configs/config.json @@ -56,6 +56,7 @@ "_comment": "See CameraConfig struct in datatypes.hpp for detailed explanations", "type": "lucid", "save_dir": "/obcpp/images/", + "save_images_to_file": true, "mock": { "images_dir": "/obcpp/tests/integration/images/saliency/" }, diff --git a/configs/dev-config.json b/configs/dev-config.json index 096ba40b..8abfaeb3 100644 --- a/configs/dev-config.json +++ b/configs/dev-config.json @@ -56,6 +56,7 @@ "_comment": "See CameraConfig struct in datatypes.hpp for detailed explanations", "type": "mock", "save_dir": "/workspaces/obcpp/images/", + "save_images_to_file": false, "mock": { "images_dir": "/workspaces/obcpp/tests/integration/images/saliency/" }, diff --git a/include/camera/interface.hpp b/include/camera/interface.hpp index 52567a13..ef7b3df5 100644 --- a/include/camera/interface.hpp +++ b/include/camera/interface.hpp @@ -45,6 +45,13 @@ struct ImageData { cv::Mat DATA; uint64_t TIMESTAMP; std::optional TELEMETRY; + + /** + * Saves the image to a file + * @param directory directory to save the image in + * @returns true/false if saving was successful + */ + bool saveToFile(std::string directory) const; }; std::string cvMatToBase64(cv::Mat image); diff --git a/include/utilities/obc_config.hpp b/include/utilities/obc_config.hpp index 36906a61..a3c4575c 100644 --- a/include/utilities/obc_config.hpp +++ b/include/utilities/obc_config.hpp @@ -119,6 +119,8 @@ struct CameraConfig { std::string type; // directory to save images to std::string save_dir; + // whether or not to save to save_dir + bool save_images_to_file; struct { // directory to randomly pick images from // for the mock camera diff --git a/src/camera/interface.cpp b/src/camera/interface.cpp index 839f5278..80c7fa94 100644 --- a/src/camera/interface.cpp +++ b/src/camera/interface.cpp @@ -69,3 +69,22 @@ std::optional queryMavlinkImageTelemetry( .roll_deg = roll_deg }; } + +bool ImageData::saveToFile(std::string directory) const { + try { + std::filesystem::path save_dir = directory; + std::filesystem::path img_filepath = + save_dir / (std::to_string(this->TIMESTAMP) + std::string(".jpg")); + std::filesystem::path json_filepath = + save_dir / (std::to_string(this->TIMESTAMP) + std::string(".json")); + saveImageToFile(this->DATA, img_filepath); + if (this->TELEMETRY.has_value()) { + saveImageTelemetryToFile(this->TELEMETRY.value(), json_filepath); + } + } catch (std::exception& e) { + LOG_F(ERROR, "Failed to save image and telemetry to file"); + return false; + } + + return true; +} diff --git a/src/network/gcs_routes.cpp b/src/network/gcs_routes.cpp index ad5ec582..61f50e8c 100644 --- a/src/network/gcs_routes.cpp +++ b/src/network/gcs_routes.cpp @@ -237,6 +237,10 @@ DEF_GCS_HANDLE(Get, camera, capture) { std::optional image = cam->takePicture(1000ms, state->getMav()); + if (state->config.camera.save_images_to_file) { + image->saveToFile(state->config.camera.save_dir); + } + if (!image.has_value()) { LOG_RESPONSE(ERROR, "Failed to capture image", INTERNAL_SERVER_ERROR); return; @@ -244,20 +248,6 @@ DEF_GCS_HANDLE(Get, camera, capture) { std::optional telemetry = image->TELEMETRY; - try { - std::filesystem::path save_dir = state->config.camera.save_dir; - std::filesystem::path img_filepath = - save_dir / (std::to_string(image->TIMESTAMP) + std::string(".jpg")); - std::filesystem::path json_filepath = - save_dir / (std::to_string(image->TIMESTAMP) + std::string(".json")); - saveImageToFile(image->DATA, img_filepath); - if (image->TELEMETRY.has_value()) { - saveImageTelemetryToFile(image->TELEMETRY.value(), json_filepath); - } - } catch (std::exception& e) { - LOG_F(ERROR, "Failed to save image and telemetry to file"); - } - ManualImage manual_image; manual_image.set_img_b64(cvMatToBase64(image->DATA)); manual_image.set_timestamp(image->TIMESTAMP); diff --git a/src/ticks/fly_search.cpp b/src/ticks/fly_search.cpp index 4780579f..f8637877 100644 --- a/src/ticks/fly_search.cpp +++ b/src/ticks/fly_search.cpp @@ -52,6 +52,9 @@ Tick* FlySearchTick::tick() { if (this->curr_mission_item != curr_waypoint) { for (int i = 0; i < this->state->config.pathing.coverage.hover.pictures_per_stop; i++) { auto photo = this->state->getCamera()->takePicture(500ms, this->state->getMav()); + if (state->config.camera.save_images_to_file) { + photo->saveToFile(state->config.camera.save_dir); + } if (photo.has_value()) { // Update the last photo time diff --git a/src/utilities/obc_config.cpp b/src/utilities/obc_config.cpp index d8fc31ab..cb7b4803 100644 --- a/src/utilities/obc_config.cpp +++ b/src/utilities/obc_config.cpp @@ -70,6 +70,7 @@ OBCConfig::OBCConfig(int argc, char* argv[]) { SET_CONFIG_OPT(camera, type); SET_CONFIG_OPT(camera, save_dir); + SET_CONFIG_OPT(camera, save_images_to_file); SET_CONFIG_OPT(camera, mock, images_dir); SET_CONFIG_OPT(camera, lucid, sensor_shutter_mode);