-
Notifications
You must be signed in to change notification settings - Fork 3
[RSDK-11250, RSDK-11251, RSDK-11784, RSDK-11807] - Cpp improvements #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
8b8430d
bfacd8a
7f320ac
5302f27
f30f89a
e561abd
dd28139
f6b2adc
b8cbc64
19e0918
de8d9b6
e466d23
b59e334
e911063
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,22 +12,20 @@ using namespace viam::sdk; | |
|
|
||
| CSICamera::CSICamera(const std::string name, const ProtoStruct& attrs) : Camera(std::move(name)) { | ||
| device = get_device_type(); | ||
| std::cout << "Creating CSICamera with name: " << name << std::endl; | ||
| std::cout << "Device type: " << device.name << std::endl; | ||
| VIAM_SDK_LOG(debug) << "Creating CSICamera with name: " << name; | ||
| VIAM_SDK_LOG(debug) << "Device type: " << device.name; | ||
| init(attrs); | ||
| } | ||
|
|
||
| CSICamera::~CSICamera() { | ||
| std::cout << "Destroying CSICamera" << std::endl; | ||
| VIAM_SDK_LOG(debug) << "Destroying CSICamera"; | ||
| stop_pipeline(); | ||
| } | ||
|
|
||
| void CSICamera::init(const ProtoStruct& attrs) { | ||
| validate_attrs(attrs); | ||
| auto pipeline_args = create_pipeline(); | ||
| if (debug) { | ||
| std::cout << "pipeline_args: " << pipeline_args << std::endl; | ||
| } | ||
| VIAM_SDK_LOG(debug) << "pipeline_args: " << pipeline_args; | ||
| init_csi(pipeline_args); | ||
| } | ||
|
|
||
|
|
@@ -36,7 +34,6 @@ void CSICamera::validate_attrs(const ProtoStruct& attrs) { | |
| set_attr<int>(attrs, "height_px", &CSICamera::height_px, DEFAULT_INPUT_HEIGHT); | ||
| set_attr<int>(attrs, "frame_rate", &CSICamera::frame_rate, DEFAULT_INPUT_FRAMERATE); | ||
| set_attr<std::string>(attrs, "video_path", &CSICamera::video_path, DEFAULT_INPUT_SENSOR); | ||
| set_attr<bool>(attrs, "debug", &CSICamera::debug, false); | ||
| } | ||
|
|
||
| template <typename T> | ||
|
|
@@ -56,34 +53,27 @@ void CSICamera::set_attr(const ProtoStruct& attrs, const std::string& name, T CS | |
| } | ||
|
|
||
| void CSICamera::reconfigure(const Dependencies& deps, const ResourceConfig& cfg) { | ||
| if (debug) { | ||
| std::cout << "Reconfiguring CSI Camera module" << std::endl; | ||
| } | ||
| VIAM_SDK_LOG(debug) << "Reconfiguring CSI Camera module"; | ||
| stop_pipeline(); | ||
| auto attrs = cfg.attributes(); | ||
| init(attrs); | ||
| } | ||
|
|
||
| Camera::raw_image CSICamera::get_image(const std::string mime_type, const ProtoStruct& extra) { | ||
| if (debug) { | ||
| std::cout << "hit get_image. expecting mime_type " << mime_type << std::endl; | ||
| } | ||
| raw_image image; | ||
| image.mime_type = DEFAULT_OUTPUT_MIMETYPE; | ||
| image.bytes = get_csi_image(); | ||
| if (image.bytes.empty()) { | ||
| std::cerr << "ERROR: no bytes retrieved" << std::endl; | ||
| VIAM_SDK_LOG(error) << "no bytes retrieved from get_csi_image"; | ||
| throw Exception("no bytes retrieved from get_csi_image"); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would I'm gonna @ Lia @lia-viam There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. honestly not super important given the way we handle exceptions. note that the distinction between the thing I would suggest though is rather than logging a message then putting it in an exception, in try { my_mod.serve(); }
catch (const std::exception& e) {
VIAM_SDK_LOG(err) << e.what();
return EXIT_FAILURE;
}
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lia-viam Thanks for the explanation. I can wrap serve in a try catch, however, I thought that a throw here would get swallowed somewhere in the SDK/GRPC layer... Are you saying
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lia-viam Should I be using GRPCException here instead? My intention is just to error out on the GRPC call.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hey sean sorry I missed the ping. so my concern here was more just the duplication of throwing an error and having to log the same message. if you're implementing a method on a component then yes that gets handled by the grpc layer, although I think it should result in SDK or RDK (I forget which) logging the text of the exception you threw, so it's maybe not necessary to duplicate the logging. for exception throws not in a component method implementation (or transitively called by one) then yes a try/catch in The main takeaway is it doesn't matter a ton whether you're throwing
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks.
Ok, added try/catch block around the main function to handle this case better. Also, removed dup logging, now allowing GRPC swallow to spit out the msg. |
||
| } | ||
|
|
||
| return image; | ||
| } | ||
|
|
||
| Camera::image_collection CSICamera::get_images() { | ||
| if (debug) { | ||
| std::cout << "[get_images] start\n"; | ||
| } | ||
|
|
||
| ProtoStruct empty_extra; | ||
| // If image is not available, an exception will be thrown | ||
| raw_image image = get_image(DEFAULT_OUTPUT_MIMETYPE, empty_extra); | ||
| image.source_name = ""; // empty string because we don't have multiple sources to differentiate | ||
|
|
||
|
|
@@ -94,30 +84,30 @@ Camera::image_collection CSICamera::get_images() { | |
| auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration_since_epoch); | ||
| collection.metadata.captured_at = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>(nanoseconds); | ||
|
|
||
| if (debug) { | ||
| std::cout << "[get_images] end\n"; | ||
| } | ||
| return collection; | ||
| } | ||
|
|
||
| ProtoStruct CSICamera::do_command(const ProtoStruct& command) { | ||
| std::cerr << "do_command not implemented" << std::endl; | ||
| VIAM_SDK_LOG(error) << "do_command not implemented"; | ||
| return ProtoStruct{}; | ||
| } | ||
|
|
||
| Camera::point_cloud CSICamera::get_point_cloud(const std::string mime_type, const ProtoStruct& extra) { | ||
| std::cerr << "get_point_cloud not implemented" << std::endl; | ||
| VIAM_SDK_LOG(error) << "get_point_cloud not implemented"; | ||
| return point_cloud{}; | ||
| } | ||
|
|
||
| std::vector<GeometryConfig> CSICamera::get_geometries(const ProtoStruct& extra) { | ||
| std::cerr << "get_geometries not implemented" << std::endl; | ||
| VIAM_SDK_LOG(error) << "get_geometries not implemented"; | ||
| return std::vector<GeometryConfig>{}; | ||
| } | ||
|
|
||
| Camera::properties CSICamera::get_properties() { | ||
| std::cerr << "get_properties not implemented" << std::endl; | ||
| return properties{}; | ||
| Camera::properties p{}; | ||
| p.supports_pcd = false; | ||
| p.intrinsic_parameters.width_px = width_px; | ||
| p.intrinsic_parameters.height_px = height_px; | ||
hexbabe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return p; | ||
| } | ||
|
|
||
| void CSICamera::init_csi(const std::string pipeline_args) { | ||
|
|
@@ -131,28 +121,23 @@ void CSICamera::init_csi(const std::string pipeline_args) { | |
| std::cerr << "Failed to create the pipeline" << std::endl; | ||
| g_print("Error: %s\n", error->message); | ||
| g_error_free(error); | ||
| std::exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| // Print pipeline structure | ||
| if (debug) { | ||
| GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline_structure"); | ||
| throw Exception("Failed to create the pipeline"); | ||
| } | ||
|
|
||
| // Fetch the appsink element | ||
| appsink = gst_bin_get_by_name(GST_BIN(pipeline), "appsink0"); | ||
| if (!appsink) { | ||
| std::cerr << "Failed to get the appsink element" << std::endl; | ||
| gst_object_unref(pipeline); | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Failed to get the appsink element"); | ||
| } | ||
|
|
||
| // Start the pipeline | ||
| if (gst_element_set_state(pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { | ||
| std::cerr << "Failed to start the pipeline" << std::endl; | ||
| gst_object_unref(appsink); | ||
| gst_object_unref(pipeline); | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Failed to start the pipeline"); | ||
| } | ||
|
|
||
| // Handle async pipeline creation | ||
|
|
@@ -164,7 +149,7 @@ void CSICamera::init_csi(const std::string pipeline_args) { | |
| std::cerr << "Failed to get the bus for the pipeline" << std::endl; | ||
| gst_object_unref(appsink); | ||
| gst_object_unref(pipeline); | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Failed to get the bus for the pipeline"); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -184,7 +169,7 @@ void CSICamera::wait_pipeline() { | |
|
|
||
| if (elapsed_time >= timeout_microseconds) { | ||
| std::cerr << "Timeout: GST pipeline state change did not complete within timeout limit" << std::endl; | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Timeout: GST pipeline state change did not complete within timeout limit"); | ||
| } | ||
|
|
||
| // Wait for a short duration to avoid busy waiting | ||
|
|
@@ -195,32 +180,30 @@ void CSICamera::wait_pipeline() { | |
| std::cout << "GST pipeline state change success" << std::endl; | ||
| } else if (ret == GST_STATE_CHANGE_FAILURE) { | ||
| std::cerr << "GST pipeline failed to change state" << std::endl; | ||
| std::exit(EXIT_FAILURE); | ||
| } else if (ret = GST_STATE_CHANGE_NO_PREROLL) { | ||
| throw Exception("GST pipeline failed to change state"); | ||
| } else if (ret == GST_STATE_CHANGE_NO_PREROLL) { | ||
| std::cout << "GST pipeline changed but not enough data for preroll" << std::endl; | ||
| } else { | ||
| std::cerr << "GST pipeline failed to change state" << std::endl; | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("GST pipeline failed to change state"); | ||
| } | ||
| } | ||
|
|
||
| void CSICamera::stop_pipeline() { | ||
| if (debug) { | ||
| std::cout << "Stopping GST pipeline" << std::endl; | ||
| } | ||
| VIAM_SDK_LOG(debug) << "Stopping GST pipeline"; | ||
|
|
||
| // Check if pipeline is defined | ||
| if (pipeline == nullptr) { | ||
| std::cout << "Pipeline is not defined" << std::endl; | ||
| VIAM_SDK_LOG(error) << "Pipeline is not defined"; | ||
| return; | ||
| } | ||
|
|
||
| // Stop the pipeline | ||
| if (gst_element_set_state(pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) { | ||
| std::cerr << "Failed to stop the pipeline" << std::endl; | ||
| VIAM_SDK_LOG(error) << "Failed to stop the pipeline"; | ||
| gst_object_unref(appsink); | ||
| gst_object_unref(pipeline); | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Failed to stop the pipeline"); | ||
| } | ||
|
|
||
| // Wait for async state change | ||
|
|
@@ -242,29 +225,25 @@ void CSICamera::catch_pipeline() { | |
| switch (GST_MESSAGE_TYPE(msg)) { | ||
| case GST_MESSAGE_ERROR: | ||
| gst_message_parse_error(msg, &error, &debugInfo); | ||
| std::cerr << "Error: " << error->message << std::endl; | ||
| std::cerr << "Debug Info: " << debugInfo << std::endl; | ||
| VIAM_SDK_LOG(error) << "Error: " << error->message; | ||
| VIAM_SDK_LOG(error) << "Debug Info: " << debugInfo; | ||
| stop_pipeline(); | ||
| std::exit(EXIT_FAILURE); | ||
| throw Exception("Failed to stop the pipeline"); | ||
| break; | ||
| case GST_MESSAGE_EOS: | ||
| std::cout << "End of stream received" << std::endl; | ||
| VIAM_SDK_LOG(info) << "End of stream received"; | ||
| stop_pipeline(); | ||
| std::exit(EXIT_SUCCESS); | ||
| throw Exception("Failed to stop the pipeline"); | ||
| break; | ||
| case GST_MESSAGE_WARNING: | ||
| gst_message_parse_warning(msg, &error, &debugInfo); | ||
| if (debug) { | ||
| std::cout << "Warning: " << error->message << std::endl; | ||
| std::cout << "Debug Info: " << debugInfo << std::endl; | ||
| } | ||
| VIAM_SDK_LOG(warn) << "Warning: " << error->message; | ||
| VIAM_SDK_LOG(warn) << "Debug Info: " << debugInfo; | ||
| break; | ||
| case GST_MESSAGE_INFO: | ||
| gst_message_parse_info(msg, &error, &debugInfo); | ||
| if (debug) { | ||
| std::cout << "Info: " << error->message << std::endl; | ||
| std::cout << "Debug Info: " << debugInfo << std::endl; | ||
| } | ||
| VIAM_SDK_LOG(info) << "Info: " << error->message; | ||
| VIAM_SDK_LOG(info) << "Debug Info: " << debugInfo; | ||
| break; | ||
| default: | ||
| // Ignore other message types | ||
|
|
@@ -355,10 +334,6 @@ int CSICamera::get_frame_rate() const { | |
| return frame_rate; | ||
| } | ||
|
|
||
| bool CSICamera::is_debug() const { | ||
| return debug; | ||
| } | ||
|
|
||
| GstElement* CSICamera::get_appsink() const { | ||
| return appsink; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,8 @@ | |
| #include <viam/sdk/config/resource.hpp> | ||
| #include <viam/sdk/resource/reconfigurable.hpp> | ||
| #include <viam/sdk/common/proto_value.hpp> | ||
| #include <viam/sdk/log/logging.hpp> | ||
| #include <viam/sdk/common/exception.hpp> | ||
|
|
||
| #include "utils.h" | ||
|
|
||
|
|
@@ -23,7 +25,6 @@ class CSICamera : public Camera, public Reconfigurable { | |
| device_type device; | ||
|
|
||
| // Camera | ||
| bool debug; | ||
| int width_px = 0; | ||
| int height_px = 0; | ||
| int frame_rate = 0; | ||
|
|
@@ -71,7 +72,6 @@ class CSICamera : public Camera, public Reconfigurable { | |
|
|
||
| // Getters | ||
| std::string get_name() const; | ||
| bool is_debug() const; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing debug attribute |
||
| int get_width_px() const; | ||
| int get_height_px() const; | ||
| int get_frame_rate() const; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| #include <viam/sdk/resource/resource.hpp> | ||
| #include <viam/sdk/registry/registry.hpp> | ||
| #include <viam/sdk/components/camera.hpp> | ||
| #include <viam/sdk/log/logging.hpp> | ||
|
|
||
| #include "constraints.h" | ||
| #include "csi_camera.h" | ||
|
|
@@ -15,22 +16,20 @@ | |
| using namespace viam::sdk; | ||
|
|
||
| int main(int argc, char *argv[]) { | ||
| std::cout << "### STARTING VIAM CSI CAMERA MODULE" << std::endl; | ||
| // Every Viam C++ SDK program must have one and only one Instance object | ||
| // which is created before any other C++ SDK objects and stays alive until | ||
| // all Viam C++ SDK objects are destroyed. | ||
| Instance inst; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to move |
||
|
|
||
| VIAM_SDK_LOG(info) << "### STARTING VIAM CSI CAMERA MODULE"; | ||
|
|
||
| // Gstreamer initialization | ||
| gst_init(&argc, &argv); | ||
|
|
||
| // Device type and params | ||
| auto device = get_device_type(); | ||
| auto api_params = get_api_params(device); | ||
|
|
||
| std::cout << "Device type: " << device.name << std::endl; | ||
| std::cout << "API Namespace: " << api_params.api_namespace << std::endl; | ||
|
|
||
| // Every Viam C++ SDK program must have one and only one Instance object | ||
| // which is created before any other C++ SDK objects and stays alive until | ||
| // all Viam C++ SDK objects are destroyed. | ||
| Instance inst; | ||
| VIAM_SDK_LOG(info) << "Device type: " << device.name; | ||
|
|
||
| auto module_registration = std::make_shared<ModelRegistration>( | ||
| API::get<Camera>(), | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.