diff --git a/.github/workflows/cpp-linter.yml b/.github/workflows/cpp-linter.yml new file mode 100644 index 0000000..61d01ed --- /dev/null +++ b/.github/workflows/cpp-linter.yml @@ -0,0 +1,68 @@ +name: C++ Lint and Auto-Fix + +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: write # Required for pushing auto-fix commits + +jobs: + lint: + name: Lint C++ Code + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} # Checkout the correct branch + fetch-depth: 0 # Ensure full commit history for pushing changes + + - name: Install clang-format and cppcheck + run: sudo apt-get install -y clang-format cppcheck + + - name: Run clang-format and fix issues + run: | + FILES=$(find . -type f \( -name "*.cpp" -o -name "*.hpp" -o -name "*.h" \) | tr '\n' ' ') + if [ -z "$FILES" ]; then + echo "No C++ source files found. Skipping clang-format." + exit 0 + fi + + clang-format -i $FILES + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + # Ensure we are on the correct branch + git checkout ${{ github.head_ref }} + + git add . + if ! git diff --cached --quiet; then + git commit -m "Auto-format C++ code using clang-format" + git push origin ${{ github.head_ref }} + fi + + - name: Run cppcheck (C++ Mode) + run: | + FILES=$(find . -type f \( -name "*.cpp" -o -name "*.hpp" -o -name "*.h" \) | tr '\n' ' ') + if [ -z "$FILES" ]; then + echo "No C++ source files found. Skipping cppcheck." + exit 0 + fi + + echo "Running cppcheck on: $FILES" + cppcheck --enable=all --error-exitcode=1 --inline-suppr --force --quiet --language=c++ \ + --suppress=missingInclude \ + --suppress=missingIncludeSystem \ + --suppress=unusedStructMember \ + --suppress=noExplicitConstructor \ + --suppress=passedByValue \ + --suppress=useInitializationList \ + --suppress=cstyleCast \ + --suppress=unusedFunction \ + --suppress=unmatchedSuppression $FILES diff --git a/src/BooleanValueSender.h b/src/BooleanValueSender.h index 099bb5b..62d6f4a 100644 --- a/src/BooleanValueSender.h +++ b/src/BooleanValueSender.h @@ -8,11 +8,11 @@ #include "networktables/NetworkTableInstance.h" class BooleanValueSender { - private: +private: nt::NetworkTableInstance inst_; nt::BooleanPublisher publisher_; - public: +public: // Constructor declaration BooleanValueSender(std::string key); diff --git a/src/DoubleArraySender.h b/src/DoubleArraySender.h index 69c5552..7258b34 100644 --- a/src/DoubleArraySender.h +++ b/src/DoubleArraySender.h @@ -9,11 +9,11 @@ #include "networktables/NetworkTableInstance.h" class DoubleArraySender { - private: +private: nt::NetworkTableInstance inst_; nt::DoubleArrayPublisher publisher_; - public: +public: // Constructor declaration DoubleArraySender(std::string key); diff --git a/src/DoubleValueSender.h b/src/DoubleValueSender.h index 5fb901b..8e8c6a9 100644 --- a/src/DoubleValueSender.h +++ b/src/DoubleValueSender.h @@ -8,11 +8,11 @@ #include "networktables/NetworkTableInstance.h" class DoubleValueSender { - private: +private: nt::NetworkTableInstance inst_; nt::DoublePublisher publisher_; - public: +public: // Constructor declaration DoubleValueSender(std::string key); diff --git a/src/IntegerArraySender.h b/src/IntegerArraySender.h index 895ffb2..bfabcf7 100644 --- a/src/IntegerArraySender.h +++ b/src/IntegerArraySender.h @@ -10,11 +10,11 @@ #include "networktables/NetworkTableInstance.h" class IntegerArraySender { - private: +private: nt::NetworkTableInstance inst_; nt::IntegerArrayPublisher publisher_; - public: +public: // Constructor declaration IntegerArraySender(std::string key); diff --git a/src/IntegerValueSender.h b/src/IntegerValueSender.h index c884b3e..d1c27ad 100644 --- a/src/IntegerValueSender.h +++ b/src/IntegerValueSender.h @@ -8,11 +8,11 @@ #include "networktables/NetworkTableInstance.h" class IntegerValueSender { - private: +private: nt::NetworkTableInstance inst_; nt::IntegerPublisher publisher_; - public: +public: // Constructor declaration IntegerValueSender(std::string key); diff --git a/src/NetworkTablesConfig.h b/src/NetworkTablesConfig.h index 95805b0..4b15dcf 100644 --- a/src/NetworkTablesConfig.h +++ b/src/NetworkTablesConfig.h @@ -1,7 +1,7 @@ #ifndef NETWORK_TABLES_CONFIG_H_ #define NETWORK_TABLES_CONFIG_H_ -inline const char* TABLE_ADDRESS = "10.7.66.2"; -inline const char* TABLE_NAME = "/SmartDashboard"; +inline const char *TABLE_ADDRESS = "10.7.66.2"; +inline const char *TABLE_NAME = "/SmartDashboard"; #endif diff --git a/src/NetworkTablesUtil.cpp b/src/NetworkTablesUtil.cpp index 455a845..a2ba1d5 100644 --- a/src/NetworkTablesUtil.cpp +++ b/src/NetworkTablesUtil.cpp @@ -3,11 +3,9 @@ #include "NetworkTablesConfig.h" NetworkTablesUtil::NetworkTablesUtil() { -// inst_ = nt::NetworkTableInstance::GetDefault(); -// inst_.SetServer(TABLE_ADDRESS); -// inst_.StartClient4(TABLE_ADDRESS); + // inst_ = nt::NetworkTableInstance::GetDefault(); + // inst_.SetServer(TABLE_ADDRESS); + // inst_.StartClient4(TABLE_ADDRESS); } -double NetworkTablesUtil::getTime() { - return wpi::GetSystemTime(); -} +double NetworkTablesUtil::getTime() { return wpi::GetSystemTime(); } diff --git a/src/NetworkTablesUtil.h b/src/NetworkTablesUtil.h index 1ba1068..0914e39 100644 --- a/src/NetworkTablesUtil.h +++ b/src/NetworkTablesUtil.h @@ -1,16 +1,15 @@ #ifndef NETWORKTABLESUTIL_H #define NETWORKTABLESUTIL_H - -//#include "networktables/NetworkTable.h" -//#include "networktables/NetworkTableInstance.h" +// #include "networktables/NetworkTable.h" +// #include "networktables/NetworkTableInstance.h" #include "wpi/timestamp.h" class NetworkTablesUtil { - //private: - //nt::NetworkTableInstance inst_; + // private: + // nt::NetworkTableInstance inst_; - public: +public: // Constructor declaration NetworkTablesUtil(); diff --git a/src/apriltag_gpu.h b/src/apriltag_gpu.h index ac5a093..3a3f00d 100644 --- a/src/apriltag_gpu.h +++ b/src/apriltag_gpu.h @@ -15,7 +15,7 @@ namespace frc971::apriltag { // Class to find the blob index of a point in a point vector. class BlobExtentsIndexFinder { - public: +public: BlobExtentsIndexFinder(const MinMaxExtents *extents_device, size_t num_extents) : extents_device_(extents_device), num_extents_(num_extents) {} @@ -45,7 +45,7 @@ class BlobExtentsIndexFinder { return extents_device_[index]; } - private: +private: const MinMaxExtents *extents_device_; size_t num_extents_; @@ -75,7 +75,7 @@ struct DistCoeffs { // GPU based april tag detector. class GpuDetector { - public: +public: // The number of blobs we will consider when counting april tags. static constexpr size_t kMaxBlobs = IndexPoint::kMaxBlobs; @@ -138,8 +138,8 @@ class GpuDetector { return extents_device_.Copy(NumQuads()); } - std::vector> CopySelectedExtents() - const { + std::vector> + CopySelectedExtents() const { return selected_extents_device_.Copy(NumQuads()); } @@ -199,7 +199,7 @@ class GpuDetector { static bool UnDistort(double *u, double *v, const CameraMatrix *camera_matrix, const DistCoeffs *distortion_coefficients); - private: +private: void UpdateFitQuads(); void AdjustPixelCenters(); @@ -209,8 +209,7 @@ class GpuDetector { static void QuadDecodeTask(void *_u); // Creates a GPU image wrapped around the provided memory. - template - GpuImage ToGpuImage(GpuMemory &memory) { + template GpuImage ToGpuImage(GpuMemory &memory) { if (memory.size() == width_ * height_) { return GpuImage{ .data = memory.get(), @@ -359,6 +358,6 @@ class GpuDetector { zarray_t *detections_ = nullptr; }; -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_ORIN_APRILTAG_H_ +#endif // FRC971_ORIN_APRILTAG_H_ diff --git a/src/cameraexception.h b/src/cameraexception.h index efb66e9..76e64d5 100644 --- a/src/cameraexception.h +++ b/src/cameraexception.h @@ -2,8 +2,8 @@ #define CAMERAEXCEPTION_H_ class CameraException : public std::exception { - public: - const char* what() const noexcept override { +public: + const char *what() const noexcept override { return "Error: No camera detected."; } }; diff --git a/src/cuda_frc971.h b/src/cuda_frc971.h index 7873760..dd98f92 100644 --- a/src/cuda_frc971.h +++ b/src/cuda_frc971.h @@ -11,9 +11,9 @@ // CHECKs that a cuda method returned success. // TODO(austin): This will not handle if and else statements quite right, fix if // we care. -#define CHECK_CUDA(condition) \ - if (auto c = condition) \ - LOG(FATAL) << "Check failed: " #condition " (" << cudaGetErrorString(c) \ +#define CHECK_CUDA(condition) \ + if (auto c = condition) \ + LOG(FATAL) << "Check failed: " #condition " (" << cudaGetErrorString(c) \ << ") " namespace frc971::apriltag { @@ -21,7 +21,7 @@ namespace frc971::apriltag { // Class to manage the lifetime of a Cuda stream. This is used to provide // relative ordering between kernels on the same stream. class CudaStream { - public: +public: CudaStream() { CHECK_CUDA(cudaStreamCreate(&stream_)); } CudaStream(const CudaStream &) = delete; @@ -32,14 +32,14 @@ class CudaStream { // Returns the stream. cudaStream_t get() { return stream_; } - private: +private: cudaStream_t stream_; }; // Class to manage the lifetime of a Cuda Event. Cuda events are used for // timing events on a stream. class CudaEvent { - public: +public: CudaEvent() { CHECK_CUDA(cudaEventCreate(&event_)); } CudaEvent(const CudaEvent &) = delete; @@ -64,15 +64,14 @@ class CudaEvent { // Waits until the event has been triggered. void Synchronize() { CHECK_CUDA(cudaEventSynchronize(event_)); } - private: +private: cudaEvent_t event_; }; // Class to manage the lifetime of page locked host memory for fast copies back // to host memory. -template -class HostMemory { - public: +template class HostMemory { +public: // Allocates a block of memory for holding up to size objects of type T. HostMemory(size_t size) { T *memory; @@ -100,14 +99,13 @@ class HostMemory { memcpy(other, span_.data(), sizeof(T) * size()); } - private: +private: std::span span_; }; // Class to manage the lifetime of device memory. -template -class GpuMemory { - public: +template class GpuMemory { +public: // Allocates a block of memory for holding up to size objects of type T in // device memory. GpuMemory(size_t size) : size_(size) { @@ -190,7 +188,7 @@ class GpuMemory { // it. std::vector Copy() const { return Copy(size_); } - private: +private: T *memory_; const size_t size_; }; @@ -203,6 +201,6 @@ void CheckAndSynchronize(std::string_view message = ""); void MaybeCheckAndSynchronize(); void MaybeCheckAndSynchronize(std::string_view message); -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_ORIN_CUDA_H_ +#endif // FRC971_ORIN_CUDA_H_ diff --git a/src/gpu_image.h b/src/gpu_image.h index 732b256..64def29 100644 --- a/src/gpu_image.h +++ b/src/gpu_image.h @@ -1,8 +1,7 @@ #ifndef FRC971_ORIN_GPU_IMAGE_H_ #define FRC971_ORIN_GPU_IMAGE_H_ -template -struct GpuImage { +template struct GpuImage { typedef T type; T *data; size_t rows; @@ -11,4 +10,4 @@ struct GpuImage { size_t step; }; -#endif // FRC971_ORIN_GPU_IMAGE_H_ +#endif // FRC971_ORIN_GPU_IMAGE_H_ diff --git a/src/json_test.cpp b/src/json_test.cpp index 0802c42..93c01de 100644 --- a/src/json_test.cpp +++ b/src/json_test.cpp @@ -5,9 +5,8 @@ #include using json = nlohmann::json; int main(void) { - std::ifstream f( - "/home/nvidia/code/OrinVisionSystem/cameracalibration/" - "calibrationmatrix.json"); + std::ifstream f("/home/nvidia/code/OrinVisionSystem/cameracalibration/" + "calibrationmatrix.json"); json data = json::parse(f); std::cout << "Matrix: " << std::endl; for (int i = 0; i < 3; ++i) { diff --git a/src/labeling_allegretti_2019_BKE.h b/src/labeling_allegretti_2019_BKE.h index d139c9d..99bebe4 100644 --- a/src/labeling_allegretti_2019_BKE.h +++ b/src/labeling_allegretti_2019_BKE.h @@ -10,4 +10,4 @@ void LabelImage(const GpuImage input, GpuImage output, GpuImage union_markers_size_device, cudaStream_t stream); -#endif // FRC971_ORIN_LABELING_ALLEGRETTI_2019_BKE_H_ +#endif // FRC971_ORIN_LABELING_ALLEGRETTI_2019_BKE_H_ diff --git a/src/line_fit_filter.h b/src/line_fit_filter.h index ce33d3b..e9410a6 100644 --- a/src/line_fit_filter.h +++ b/src/line_fit_filter.h @@ -90,7 +90,7 @@ struct LineFitMoments { int64_t Mxx; int64_t Myy; int64_t Mxy; - int N; // how many points are included in the set? + int N; // how many points are included in the set? }; std::ostream &operator<<(std::ostream &os, @@ -113,8 +113,8 @@ struct PeakExtents { struct PeakDecomposer { static constexpr size_t kBitsInKey = 16 + 32; - __host__ __device__ ::cuda::std::tuple operator()( - Peak &key) const { + __host__ __device__ ::cuda::std::tuple + operator()(Peak &key) const { return {key.blob_index, key.error}; } }; @@ -159,6 +159,6 @@ __host__ __device__ std::tuple Unrank(uint i); // The max number of work elements for a max maxes of 10. constexpr size_t MaxRankedIndex() { return 210; } -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_ORIN_LINE_FIT_FILTER_H_ +#endif // FRC971_ORIN_LINE_FIT_FILTER_H_ diff --git a/src/points.h b/src/points.h index 745e151..a6194da 100644 --- a/src/points.h +++ b/src/points.h @@ -82,14 +82,14 @@ struct QuadBoundaryPoint { // Returns the change in x derived from the search direction. __forceinline__ __host__ __device__ int32_t dx() const { switch (key & 0x3) { - case 0: - return 1; - case 1: - return 1; - case 2: - return 0; - case 3: - return -1; + case 0: + return 1; + case 1: + return 1; + case 2: + return 0; + case 3: + return -1; } return 0; } @@ -97,12 +97,12 @@ struct QuadBoundaryPoint { // Returns the change in y derived from the search direction. __forceinline__ __host__ __device__ int32_t dy() const { switch (key & 0x3) { - case 0: - return 0; - case 1: - case 2: - case 3: - return 1; + case 0: + return 0; + case 1: + case 2: + case 3: + return 1; } return 0; } @@ -125,8 +125,8 @@ struct QuadBoundaryPoint { } // Returns the black to white or white to black bit. - __forceinline__ __host__ __device__ void set_black_to_white( - bool black_to_white) { + __forceinline__ __host__ __device__ void + set_black_to_white(bool black_to_white) { key = (key & 0xfffffffffffffff7ull) | (static_cast(black_to_white) << 3); } @@ -135,16 +135,16 @@ struct QuadBoundaryPoint { } // Various operators to make it easy to compare points. - __forceinline__ __host__ __device__ bool operator!=( - const QuadBoundaryPoint other) const { + __forceinline__ __host__ __device__ bool + operator!=(const QuadBoundaryPoint other) const { return other.key != key; } - __forceinline__ __host__ __device__ bool operator==( - const QuadBoundaryPoint other) const { + __forceinline__ __host__ __device__ bool + operator==(const QuadBoundaryPoint other) const { return other.key == key; } - __forceinline__ __host__ __device__ bool operator<( - const QuadBoundaryPoint other) const { + __forceinline__ __host__ __device__ bool + operator<(const QuadBoundaryPoint other) const { return key < other.key; } @@ -223,26 +223,26 @@ struct IndexPoint { __forceinline__ __host__ __device__ int32_t dx() const { switch (key & 0x3) { - case 0: - return 1; - case 1: - return 1; - case 2: - return 0; - case 3: - return -1; + case 0: + return 1; + case 1: + return 1; + case 2: + return 0; + case 3: + return -1; } return 0; } __forceinline__ __host__ __device__ int32_t dy() const { switch (key & 0x3) { - case 0: - return 0; - case 1: - case 2: - case 3: - return 1; + case 0: + return 0; + case 1: + case 2: + case 3: + return 1; } return 0; } @@ -265,8 +265,8 @@ struct IndexPoint { return key & 0xffffff; } - __forceinline__ __host__ __device__ void set_black_to_white( - bool black_to_white) { + __forceinline__ __host__ __device__ void + set_black_to_white(bool black_to_white) { key = (key & 0xfffffffffffffff7ull) | (static_cast(black_to_white) << 3); } @@ -282,20 +282,20 @@ std::ostream &operator<<(std::ostream &os, const IndexPoint &point); // Decomposer for sorting which just returns the key. struct QuadBoundaryPointDecomposer { - __host__ __device__ ::cuda::std::tuple operator()( - QuadBoundaryPoint &key) const { + __host__ __device__ ::cuda::std::tuple + operator()(QuadBoundaryPoint &key) const { return {key.key}; } }; // Decomposer for sorting which just returns the key. struct QuadIndexPointDecomposer { - __host__ __device__ ::cuda::std::tuple operator()( - IndexPoint &key) const { + __host__ __device__ ::cuda::std::tuple + operator()(IndexPoint &key) const { return {key.key}; } }; -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_ORIN_POINTS_H_ +#endif // FRC971_ORIN_POINTS_H_ diff --git a/src/threshold.h b/src/threshold.h index 56f2314..4eb5f30 100644 --- a/src/threshold.h +++ b/src/threshold.h @@ -15,6 +15,6 @@ void CudaToGreyscaleAndDecimateHalide( uint8_t *thresholded_image, size_t width, size_t height, size_t min_white_black_diff, CudaStream *stream); -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_ORIN_THRESHOLD_H_ +#endif // FRC971_ORIN_THRESHOLD_H_ diff --git a/src/transform_output_iterator.h b/src/transform_output_iterator.h index cdda637..ca3c39e 100644 --- a/src/transform_output_iterator.h +++ b/src/transform_output_iterator.h @@ -7,7 +7,7 @@ namespace frc971::apriltag { template class TransformOutputIterator { - private: +private: // proxy object to be able to convert when assigning value struct Reference { OutputType *ptr; @@ -20,7 +20,7 @@ class TransformOutputIterator { } }; - public: +public: // typedefs may not be neeeded for iterator to work but is here to maintain // similarity to cub's CacheModifiedOutputIterator typedef TransformOutputIterator self_type; @@ -69,22 +69,22 @@ class TransformOutputIterator { } // equal to - __host__ __device__ __forceinline__ bool operator==( - const TransformOutputIterator &rhs) const { + __host__ __device__ __forceinline__ bool + operator==(const TransformOutputIterator &rhs) const { return ptr == rhs.ptr; } // not equal to - __host__ __device__ __forceinline__ bool operator!=( - const TransformOutputIterator &rhs) const { + __host__ __device__ __forceinline__ bool + operator!=(const TransformOutputIterator &rhs) const { return ptr != rhs.ptr; } - private: +private: const ConversionOp convert_op; OutputType *ptr; }; -} // namespace frc971::apriltag +} // namespace frc971::apriltag -#endif // FRC971_TRANSFORM_OUTPUT_ITERATOR_ +#endif // FRC971_TRANSFORM_OUTPUT_ITERATOR_ diff --git a/src/video_processor.h b/src/video_processor.h index c022665..1897082 100644 --- a/src/video_processor.h +++ b/src/video_processor.h @@ -11,10 +11,10 @@ using namespace std; using namespace cv; class VideoProcessor { - public: - VideoProcessor(const int camera_index, const std::string& tag_family_name, - const frc971::apriltag::CameraMatrix& camera_matrix, - const frc971::apriltag::DistCoeffs& distortion_coefficients, +public: + VideoProcessor(const int camera_index, const std::string &tag_family_name, + const frc971::apriltag::CameraMatrix &camera_matrix, + const frc971::apriltag::DistCoeffs &distortion_coefficients, int nthreads = 4); ~VideoProcessor(); @@ -22,14 +22,14 @@ class VideoProcessor { bool initialize(); bool process(); - private: - const std::string& tag_family_name_; +private: + const std::string &tag_family_name_; int camera_index_; - const frc971::apriltag::CameraMatrix& camera_matrix_; - const frc971::apriltag::DistCoeffs& distortion_coefficients_; + const frc971::apriltag::CameraMatrix &camera_matrix_; + const frc971::apriltag::DistCoeffs &distortion_coefficients_; int nthreads_; - apriltag_family_t* tf_; - apriltag_detector_t* td_; + apriltag_family_t *tf_; + apriltag_detector_t *td_; std::unique_ptr cap_; std::unique_ptr gpu_detector_; bool initialized_; diff --git a/src/ws_test.cpp b/src/ws_test.cpp index f9c8a59..13def02 100644 --- a/src/ws_test.cpp +++ b/src/ws_test.cpp @@ -48,19 +48,19 @@ using namespace cv; using namespace seasocks; class MyHandler : public WebSocket::Handler { - public: - explicit MyHandler(Server* server) : _server(server) {} +public: + explicit MyHandler(Server *server) : _server(server) {} - void onConnect(WebSocket* connection) override { + void onConnect(WebSocket *connection) override { _connections.insert(connection); std::cout << "Connected: " << connection->getRequestUri() << " : " << formatAddress(connection->getRemoteAddress()) << "\nCredentials: " << *(connection->credentials()) << "\n"; } - void onData(WebSocket* connection, const char* data) override {} + void onData(WebSocket *connection, const char *data) override {} - void sendImage(const cv::Mat& image) { + void sendImage(const cv::Mat &image) { for (auto c : _connections) { std::vector buf; cv::imencode(".jpg", image, buf); @@ -68,15 +68,15 @@ class MyHandler : public WebSocket::Handler { } } - void onDisconnect(WebSocket* connection) override { + void onDisconnect(WebSocket *connection) override { _connections.erase(connection); std::cout << "Disconnected: " << connection->getRequestUri() << " : " << formatAddress(connection->getRemoteAddress()) << "\n"; } - private: - std::set _connections; - Server* _server; +private: + std::set _connections; + Server *_server; }; void send_data(std::shared_ptr handler) { @@ -87,7 +87,7 @@ void send_data(std::shared_ptr handler) { } } -int main(int /*argc*/, const char* /*argv*/[]) { +int main(int /*argc*/, const char * /*argv*/[]) { auto logger = std::make_shared(Logger::Level::Debug); Server server(logger);