-
Notifications
You must be signed in to change notification settings - Fork 0
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
CV Pipeline Integration #73
Conversation
Going to also ping @dzodkin33 since I touched some of the CameraInterface code to get the MockCamera up and running. Also want to ping @hashreds and @cr1t1cql since they will be filling in some of the modules of the pipeline. |
empty classes/methods for CV pipeline. this commit will define the types and layout of inputs/outputs of each stage of the pipeline. includes the following modules: - saliency - localization - matching - segmentation - classification also added some additional data to ImageData that will be needed for pipeline.
right now only testing crop function
implements two methods of CameraInterface to quickly plug in something to the rest of the pipeline. For now it just generates an image of a solid color. In the future we could have it return an actual competition image with a valid target that the models can recognize. set up other CameraInterface related functions to get MockCamera working
set up tick method that captures a photo and passes it through the CV pipeline in a new thread
integration test to allow for portable testing of the entire CV pipeline using an arbitrary image as input
to match other unit test files
c9a77e6
to
534de34
Compare
I have rebased and gotten the ✅ on the commit.
I have run into this in other places in this project. I think we should make a reusable way to add this functionality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing job, Anthony. This is an extremely well made mega-PR that was a delight to review. I really liked the long-form comments you included explaining the different parts of the system. Your additions look good and are an important step to bringing the structure of remaining work into definition. I think this design allows for a good amount of wiggle room as the implementations find things that need to be changed.
|
||
#include <nlohmann/json.hpp> | ||
#include <opencv2/opencv.hpp> | ||
|
||
// class to contain all telemetry that should be tagged with an image. | ||
// In the future this could be in a mavlink file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a mavlink file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking of a mavlink.hpp
that would be added by Jasper in his Mavlink Client.
// In the future this could be in a mavlink file. | ||
class ImageTelemetry { | ||
public: | ||
ImageTelemetry(double latitude, double longitude, double altitude, double airspeed, double yaw, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could use the GPSCoord
type. I like how you made a ImageTelemetry
type so it is easy to add/remove fields in the future. I think it is more conventional to make this a struct since everything is public. Also this should have a default initializer {}
for all the values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of removing some of the fields in favor of GPSCoord
. I have also changed ImageTelemetry to a struct.
What do you mean by default initializer? Is that the same as the constructor implementation in camera/interface.cpp
? https://github.com/tritonuas/obcpp/blob/feat/cv-orchestrator/src/camera/interface.cpp#L3-L11
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that will make sure this all gets zero initialized.
@@ -50,8 +69,8 @@ class CameraConfiguration { | |||
class CameraInterface { | |||
private: | |||
CameraConfiguration config; | |||
ImageData recentPicture; // might need to move it to public | |||
bool doneTakingPicture; // overengineering time | |||
std::unique_ptr<ImageData> recentPicture; // might need to move it to public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well at least it should be fine if it's private ...because the smart pointer is handling all the scoping memory for us.
// overengineering time
🤔 I cannot give useful advice on the design of this interface ...because I have no idea what kinds of functionality we have been using in the past since '87. I do not want to block based on any minor improvements, so as long as you are happy with this we should forge ahead. That being said, it would be good to reping the people in your comment to get a better set of eyes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have removed that public comment. That was made by Boris in the original interface. And so was the over engineering comment. This PR wasn't supposed to drastically change the camera interface but we've already had a design talk with Boris during the meeting on how to simplify the API.
include/core/states.hpp
Outdated
*/ | ||
class SearchState : public MissionState { | ||
public: | ||
// Passing in a unique_ptr to a CameraInterface for dependency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your mocking approach is fine.
struct PipelineResults { | ||
ImageData imageData; | ||
std::vector<AirdropTarget> matchedTargets; | ||
// Not sure if unmatchedTargets should hold a different struct than |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure both should be the same type
src/core/states.cpp
Outdated
// Just thinking out loud regarding thread saftey here. With the code below, | ||
// we will be capturing a new image from the camera and running it through | ||
// the models of the CV pipeline once on every tick (every second or so). | ||
// In terms of potential data races here are a few I can think of: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply design your system to be impossible to have data races and then put it in the appendix.
src/core/states.cpp
Outdated
// TODO: send to GCS for verification | ||
}); | ||
|
||
// TODO: Need a way to cleanup any running threads when the state changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point worth emphasizing. I think we can use a smart pointer for the state which will automatically call destructors for each state when needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually Tyler already brought up these concerns here #55 (comment)
Thank you for getting the lint up to spec. Much appreciated. |
* update ubuntu version 🙏 * fix groupadd command
* update ubuntu version 🙏 * fix groupadd command * fix error
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN?
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN? * install cpplint through apt instead of pip3
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN? * install cpplint through apt instead of pip3 * try to fix user id
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN? * install cpplint through apt instead of pip3 * try to fix user id * i am at my wits end 🔫
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN? * install cpplint through apt instead of pip3 * try to fix user id * i am at my wits end 🔫 * fix dumbass merge conflict
* update ubuntu version 🙏 * fix groupadd command * fix error * fix typo * WHY THE FUCK DID IT NOT MERGE THIS IN? * install cpplint through apt instead of pip3 * try to fix user id * i am at my wits end 🔫 * fix dumbass merge conflict * fix this bullshit
…l folder and test image folder
…gmentation-integration Added models folder and test images folder.
CV segmentation integration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cv_pipeline integration tests looks like it is failing to compile for me:
/workspaces/obcpp/tests/integration/cv_pipeline.cpp: In function 'int main()':
/workspaces/obcpp/tests/integration/cv_pipeline.cpp:80:53: error: no matching function for call to 'Pipeline::Pipeline(std::array<Bottle, 5>&, std::vector<std::pair<cv::Mat, unsigned char> >&)'
80 | Pipeline pipeline(bottlesToDrop, referenceImages);
| ^
In file included from /workspaces/obcpp/tests/integration/cv_pipeline.cpp:5:
/workspaces/obcpp/include/cv/pipeline.hpp:35:9: note: candidate: 'Pipeline::Pipeline(std::array<Bottle, 5>, std::vector<std::pair<cv::Mat, BottleDropIndex> >)'
35 | Pipeline(std::array<Bottle, NUM_AIRDROP_BOTTLES> competitionObjectives,
| ^~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:36:62: note: no known conversion for argument 2 from 'vector<pair<[...],unsigned char>>' to 'vector<pair<[...],BottleDropIndex>>'
36 | std::vector<std::pair<cv::Mat, BottleDropIndex>> referenceImages);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate: 'Pipeline::Pipeline(const Pipeline&)'
33 | class Pipeline {
| ^~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate expects 1 argument, 2 provided
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate: 'Pipeline::Pipeline(Pipeline&&)'
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate expects 1 argument, 2 provided
make[3]: *** [CMakeFiles/cv_pipeline.dir/build.make:496: CMakeFiles/cv_pipeline.dir/tests/integration/cv_pipeline.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:421: CMakeFiles/cv_pipeline.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:428: CMakeFiles/cv_pipeline.dir/rule] Error 2
make: *** [Makefile:221: cv_pipeline] Error 2
Also, it would be good to change all of the couts and cerrs through the cv code to use the logging library instead.
I like the general structure of the CV stuff though. It should be easy to slot everything in where they need to go.
cv_pipeline should compile now. We moved some stuff to use some of the protobuf structs but forgot to update it in the cv_pipeline test. Before this gets merged in I want to
@shijiew555 and @hashreds can merge in their changes to main for classification and saliency respectively. We want to get this branch merged in as soon as possible so that other branches can depend on the existing changes. |
also added some comments for some of the cv test files
also removed some hardcoded model paths and moved them to constructors
we need to debug the ECEF localization algorithm but it's out of the scope of the feat/cv-orchestrator PR and I want a green checkmark
also improved error messages when model can't be loaded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like all of the code structure and organization for everything. I had the issue with the image paths, but I think that's just a me issue and I don't think its worth holding up the merge over it. Once we automate the asset pulling process fully we can rigorously test to make sure everything is robust.
Closes #62
Closes #30
Changes
Set up a skeleton of the Computer Vision pipeline. This includes classes and function signatures for all modules of the pipeline. Now, the types of output data of each stage of the pipeline is well defined.
Also created a
SearchState
class that inherits fromMissionState
. In its tick function it starts up a new thread that captures a new image from the camera and passes it into the pipeline. I have not implemented any way to collect results from multiple threads, send the results to the GCS, or shut down threads that exceed a timeout. These should be done in a later PR.This PR also includes a
MockCamera
implementation that implementsCameraInterface
. I just added it to easily be able to fetch dummy image data. Right now it just returns an image with a solid color but in the future it should return an image with valid competition targets.Testing
There's a small unit test to test an image crop helper function.
tests/unit/cv/utilities_test.cpp
There's another unit test to test the mock camera
test/unit/camera/mock.cpp
There's an integration test to allow someone to run the entire CV pipeline using an arbitrary image from a filepath.
tests/integration/pipeline.cpp
Feedback
Any feedback is appreciated, but I'd like to focus on a few specific parts.
CameraInterface
. It can be found here based on the first approach in this blog post.