From 4a6908df184554db3f15b08fe1368245d769d297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=98=8C?= <392871505@qq.com> Date: Sun, 17 May 2026 22:28:17 +0800 Subject: [PATCH] fix(ros): Update ROS wrapper to match current Pipeline API - Rewrite acoustic_node.cpp: - Use PipelineConfig instead of removed PipelineParams - Use Pipeline::Process(flat_samples) returning AcousticFrame - Remove obsolete init() and process_single_channel() calls - Add flatten_audio helper for interleaved multi-channel data - Rewrite threat_publisher.cpp: - Implement ThreatPublisher::Impl PIMPL pattern - Accept AcousticFrame instead of old TrackedThreat vector - Add NumPublished() counter - Fix CMakeLists.txt: remove stale KISSFFT_DIR from test includes - Add build_core_test.bat for compiling all test targets on Windows - All core tests pass (test_core_lib 6/6) --- .../src/acoustic/CMakeLists.txt | 2 +- .../src/acoustic/build/extract_mel_cpp.exe | Bin 119538 -> 115387 bytes .../acoustic/build/test_classifier_cpp.exe | Bin 149751 -> 145600 bytes .../src/acoustic/build_core_test.bat | 29 +++--- .../src/acoustic/src/ros/acoustic_node.cpp | 88 ++++++++---------- .../src/acoustic/src/ros/threat_publisher.cpp | 25 ++++- 6 files changed, 77 insertions(+), 67 deletions(-) diff --git a/src/drone-software/src/acoustic/CMakeLists.txt b/src/drone-software/src/acoustic/CMakeLists.txt index a0150e6..e39566b 100644 --- a/src/drone-software/src/acoustic/CMakeLists.txt +++ b/src/drone-software/src/acoustic/CMakeLists.txt @@ -182,7 +182,7 @@ if(BUILD_TESTS) add_executable(test_core_lib tests/test_core_lib.cpp ${CORE_BASE_SOURCES}) target_include_directories(test_core_lib PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/include ${EIGEN3_INCLUDE_DIR} ${KISSFFT_DIR}) + ${CMAKE_CURRENT_SOURCE_DIR}/include ${EIGEN3_INCLUDE_DIR}) if(NOT WIN32) target_link_libraries(test_core_lib PRIVATE m) endif() diff --git a/src/drone-software/src/acoustic/build/extract_mel_cpp.exe b/src/drone-software/src/acoustic/build/extract_mel_cpp.exe index bc788b259695bf0029bda89540f2ced52c703c82..ce056fbe7b1e37fc0f6a637fba8293eb56f8b90f 100644 GIT binary patch delta 32073 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

CZSH%5z!kf~> z{x?nRzL$23LZpy z4D~Q2jH^X`WK&O*sl#OIQ!-`tFy&ioQ}2Eo64r4Q8^Z>6zfJ}U@ckKcl0#lZ2d z)#XpTFpQ$V#ptG-wqD_B#o|DI_>^)gO3qB;|2_qqC1i7=@)~BOY;)nWGv-cyHVY`( z6esfiXEY90Ds{Va5Vj0_{z=FzmqCwsJ5onv^5=QAy!aNV~>^E7Aa?PcugqV zTh3RXg}tv}&oNO66zHdCYxvPz*-5;}yPbm{ijaThL{|W2%5NduEuu;@{xhVb(-bKm zA>-LOs3`uv+l^3Ae?+mFX>#S$`1tdlh3?^J&ZE#Y)w47nc%g<+l;m5Fw=KXLeORqk zv0N+ZfG_{?0uCJ0pDaGF8kskvLk3(ZNLThOY6iW*q8CR`)F*)c#ZaN8l*KFlW;wkmOc;QEdkuR$lB#kK^e z;dS`vK-PI6TRo7yTBHXGE7n3lj(Z^IJ&-RVc?7=W z5#`r|5q!ocVna#&IETNsQfv_1ITkUckx;#oh6M30Bk^_8EBGMS+SPzR5mEB-fyos5 zz$7F}2?T8`@lWPZAash1f~*8$#+z9Db-ujy#AX>ty1u5?UqBKxS`nS9L#)_I1Y)Ik z?UYoYLxA!$YCiyR!Zf+4$TY&o+Vo{Xb@5LFacv(JnQS118ku*1IMu0Fk@*0~1Z!|j z(_aG0RSS}YwDD6jQWh-{wrULh1R45~5yj9$LfkP+8$WmP5nEnOG<^|7Y-20&(d zTWb~{52#F2`=@{uXprZDxVCjl@!Np(M1j>2dY@$QPR+~h;uRo|G{ye_q=5buzq%ft zE&UKeGc_$8)fJzrYmkLN=!cJh)OfrABv#|}>p;>q4xIr)AKBtxEHbKUR{`a^)zBF; z(k9`Rr#rAzh+hImwRg?BjsjxVbUho8PMRKb3`n6y>vJHLfrt>|uNMD3AlJ@F2`v4S zMrMuLfNoFr;qgEmn&KA&DRftZoZbV(9 z9aU8>7sG)F2xB#pKnQ;HsHZqR6iA9}+GS@PkOWON_RCsEvZJ&={xK^+aJq)++d#Cz ze@JTXP9!(bR75DMW=Cs)FM2F+vAQ$H0&%GBVN7LZEKHj=cPiymkKwtOMIY-B$Yi=B z1X!2?MEO?JRgL*T3>ul&fViFpmCCNcKE7k>JEs#R1TPM6Uv(580I_I#L!cRrsI%5oO9rHTg6ry5bAaS()bfCoMb_+S zZvi=~k@*0KcCz>!NQg$}HV}sa?O)wv9|1ZH&1$b3BqF$)x;6*m`gA36>sN3;L91VpZ@yZCQ_7!*5v z^cAs*HLyQgRa1-cK2x64k+2AeNp(hX zXnhhofkUJAI)tic^C{|lro8ra)&2-%=#MPdoX^h9nl31>4P7qwgN)!)bIzL$L_QC9 zJ8c7Epzj*1J-Rf2FTEzlSY4-)ic`1AnA@qeDf8ycnKyNs17P)h@jGOcFB)Agcn?HR z*VH!@NT#Ut1~|TO+O*lQp}aJ7X|;rm(W-H(Cm`*-HyB8sPff=s0*QsO>Z;@baXsaz ztqsJinVfb4DTG6Hpov{dTF$fdBorHkUQyk)Z$T&%ovqsRF(As{lexV1wP5!t8&PV9 zIsnmbK}yU+~eT+~&ulQC~bJPl&y<*uu+y^u-KX#E3-u{|2HdWsSU zql;>KRxpr98YCTvQPXKx0x@flw@F6RY@ZOKsn~5Gf?l)6J_MAaDa`*V)J)@bIFJ-~ zU|~Wq0rAxoKNv`XJ02u67D&1VnF^!~F3NvfqXd5?pd$CYI(@;kNmHS!d@|q)zr_BXGa@AVjB6SpT^+o(q9qgp(3wQj#Ej5J#kTSU^BjgIvK#JU^ z3F!o6nP%ws1A=hWh>&*kFgT$z?Xe0hUkeM2pi$GG{cI2)+1+A4(BY1-FErd$ly@HDW9f(n1vu2)$ zb+IFcAEO zISK?~YN$(qY}J%?8A#V6znV3>1L%sTFliLpUK0=bfP~lmK@7JxKxUq%8#E(CW1uq- zr^diQAX_#5j|Nhz={!?`9Mx#81X8A{<6>(!^e2tb%MhYpboL&p0y6-B7h8XvnxNe8cc_>!5 zFiugeHI7k{CzL?QqABbXAf!?qk8&XNt472zNNT!VFc6al83&}$-FeccEm$yj9<~~} z8XxCE$mt$mRLF}!ax@NY1QMdDJ^e?TWg4yXK(sr%8$c>Gy{hS0^fT=2--;50{pE;U(&kr;Jji*O5U{(lDJa4SxyJ zm49TBTJhVhq@G8Hx0Wt?@m6ut*GKBLmk!kDA3P8{^16xA!y|!xr48PE< z?k!3}k#>Cyq7Yx#l>p5Zg=6bmG!@NksMy%o+)orP)LGvmoI93_{{DL*V8FGHZ55k$ zF-u?_xO{LO!d2^IMo#;AlPBa&5QMN;WR&4*iK~SDEVgQW8CQrRF61jD_7G6#+wn5C8Q6Kbt11J|>pC_QWe=`+?t!qNIf~3+zxnl- zb`4-X{aeOu-7ME*(;bKqVb_8HTgnem*A(h(x-AN(b6!s`UF)AHO3l-mBOq0}Kad3m zwvrAGWQlTme1#Qf=6b2nXE(kRtO#!Ccf*!D;^-8*S z>L3dGNWrq=ta0oIcKe7YEi3LMS*)K}td}g-%g!I*w^ZxhgfA@Cs}^g&7-PDvub}l922nCCiguEvDQ$zbg!Wr61b^x@QMpuY(B0VO~*@`$DxDy!8LVBTY#2U6g zC@miY%ChQr{mQLCE!MkEiF(O;51LY~4(F%HPCnL|@(M$`BI>Dzcc_f5j>TqnT5Lz_ zR8cOeNMW$$dDzlIe`W-p zEPJi~srb@&1mRb`q4N>Yglkjvkt?Z~FjfDH<5!Em%?H0G>qk0%)sH*xJf6&6){n`5 zDtScm@Z`+lPs#4f(zniwG3i?`jWJuSpTX_%`_QfbNVlGI-s?@(pD#!f^ebCn_#$%% zGM(Sl!oQ>_EDU;z@H4=>h3QvaMfEH0*XY;14rbLg{fiDz>kZ4K57GuY}>eTkGmRc{Mi3Txs#c7{@;^{5_xo?^D1tAfee$|h>Le2MKzv{C-!BsY>+aLK0 zJ_r60t}lRm{Hwk}y;GJI=f!R?;JKChIPyjud1J-dtkL7fk4+wvJT`e;^7s$V`=S{_ z<+s)_G}yTZ?VfbsS@r~|EyK@Z^GmgUXt9=AT3@i7u9hs_s`bmCBIk5FKR?J)=yTlC z?M$9esx>9w55;ezxbtPTY`V>uYCVUt>8;D%W&c85D63z71I(&xdCTF08cSinm^kX} zd2b2AAlq~3_%`?DNKZ-l$>R~~`*a)P-%^+v6Aurx`4G)LCkMg(eE1V8`XNJaK$QR5 z7all5-#&*@S9~a@cl%|*`xU7)9~K7nB|CrarG!&Tf&);&i-^qz2#hn9^JZF?gmZO8 z=cq(XN&op%E_87>3LV!J8t5rBrdFv~Ds>R0QVV@f!a@3#!I=M2t^NHf0>N0U|4p~v zwX{Ct%vq;I63Gs-wXC=+PuIw;pxnX8t=JD}Dm&JwTX0|tjD#=936{e27!&5L)H6&M z+*bPZH0v1L(Z9e*eb(%a(`DHw_Waob!kU!rq2I~SCS@lZArZtg*(9i0$EIS*!_%#| zEs8I0S*hmX!r($58h%3Mfr=aJ0a-t&xUJH^RC-6HbvCdep)FWJXi$fpZ$Pv#=n6

Ns*13)g0KiF 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 diff --git a/src/drone-software/src/acoustic/build_core_test.bat b/src/drone-software/src/acoustic/build_core_test.bat index 75b9914..7ff00b9 100644 --- a/src/drone-software/src/acoustic/build_core_test.bat +++ b/src/drone-software/src/acoustic/build_core_test.bat @@ -3,39 +3,35 @@ chcp 65001 >nul setlocal EnableDelayedExpansion echo ========================================== -echo Acoustic Core Library - Quick Build +echo Acoustic Core Library Test Build echo ========================================== set SRC_ROOT=%~dp0 set EIGEN=%SRC_ROOT%third_party\eigen-3.4.0 -set KISSFFT=%SRC_ROOT%third_party\kiss_fft set ONNX_INC=%SRC_ROOT%third_party\onnxruntime\include -set ONNX_LIB=%SRC_ROOT%third_party\onnxruntime\lib\onnxruntime.lib -set INCLUDES=-I%SRC_ROOT%include -I%EIGEN% -I%KISSFFT% -I%ONNX_INC% +set INCLUDES=-I%SRC_ROOT%include -I%EIGEN% set FLAGS=-std=c++17 -O2 -D_USE_MATH_DEFINES -Wa,-mbig-obj -set LIBS=%ONNX_LIB% if not exist build mkdir build -REM --- test_core_lib --- echo [1/3] Building test_core_lib.exe ... g++ %FLAGS% %INCLUDES% ^ tests\test_core_lib.cpp ^ src\core\fft_utils.cpp ^ src\core\audio_buffer.cpp ^ src\core\feature_extractor.cpp ^ - src\core\gcc_phat_localizer.cpp ^ src\core\distance_estimator.cpp ^ + src\core\gcc_phat_localizer.cpp ^ src\core\threat_tracker.cpp ^ + src\io\wav_file_source.cpp ^ -o build\test_core_lib.exe ^ - %LIBS% -lws2_32 + -D_stdcall= if %ERRORLEVEL% NEQ 0 ( echo [FAIL] test_core_lib build failed. exit /b 1 ) -REM --- extract_mel_cpp --- echo [2/3] Building extract_mel_cpp.exe ... g++ %FLAGS% %INCLUDES% ^ tests\extract_mel_cpp.cpp ^ @@ -43,27 +39,32 @@ g++ %FLAGS% %INCLUDES% ^ src\core\feature_extractor.cpp ^ src\io\wav_file_source.cpp ^ -o build\extract_mel_cpp.exe ^ - %LIBS% + -D_stdcall= if %ERRORLEVEL% NEQ 0 ( echo [FAIL] extract_mel_cpp build failed. exit /b 1 ) -REM --- test_classifier_cpp --- echo [3/3] Building test_classifier_cpp.exe ... -g++ %FLAGS% %INCLUDES% ^ +set ONNX_LIB=%SRC_ROOT%third_party\onnxruntime\lib\libonnxruntime.a +g++ %FLAGS% %INCLUDES% -I%ONNX_INC% ^ tests\test_classifier_cpp.cpp ^ src\core\fft_utils.cpp ^ src\core\feature_extractor.cpp ^ src\core\gunshot_classifier.cpp ^ src\io\wav_file_source.cpp ^ -o build\test_classifier_cpp.exe ^ - %LIBS% -D_stdcall= + %ONNX_LIB% -D_stdcall= if %ERRORLEVEL% NEQ 0 ( echo [FAIL] test_classifier_cpp build failed. exit /b 1 ) echo. -echo [OK] All core tests built successfully in build\ +echo [OK] All test executables built successfully. +echo. +echo Run tests: +echo build\test_core_lib.exe +echo build\extract_mel_cpp.exe dataset\binary\val\ambient\xxx.wav +echo build\test_classifier_cpp.exe --model models\gunshot_classifier.onnx --wav dataset\binary\val\ambient\xxx.wav --label_map models\label_map.json endlocal diff --git a/src/drone-software/src/acoustic/src/ros/acoustic_node.cpp b/src/drone-software/src/acoustic/src/ros/acoustic_node.cpp index 9811ba2..e1a39a7 100644 --- a/src/drone-software/src/acoustic/src/ros/acoustic_node.cpp +++ b/src/drone-software/src/acoustic/src/ros/acoustic_node.cpp @@ -83,32 +83,25 @@ private: } void init_pipeline() { - PipelineParams p; - p.feature.sample_rate = params_.sample_rate; - p.feature.n_mels = 64; - p.feature.n_fft = 2048; - p.feature.hop_length = 512; - p.feature.f_min = 0.0f; - p.feature.f_max = 8000.0f; - p.feature.preemphasis = 0.97f; - p.model_path = params_.model_path; - p.label_map_path = params_.label_map_path; - p.sample_rate = params_.sample_rate; - p.mic_geometry.num_mics = params_.n_channels; - p.mic_geometry.layout = "cross"; - p.mic_geometry.spacing = 0.15f; - pipeline_ = std::make_unique(p); - if (!pipeline_->init()) { - ROS_ERROR("Pipeline initialization failed"); - } + PipelineConfig config; + config.sample_rate = static_cast(params_.sample_rate); + config.chunk_duration = params_.chunk_duration; + config.hop_duration = params_.hop_duration; + config.n_mels = 64; + config.classifier.model_path = params_.model_path; + config.classifier.label_map_path = params_.label_map_path; + config.classifier.threshold = 0.7f; + config.classifier.smoothing_window = 3; + config.mic_array.num_mics = static_cast(params_.n_channels); + config.mic_array.layout = "cross"; + config.mic_array.spacing = 0.15f; + pipeline_ = std::make_unique(config); } void init_source() { if (source_type_ == "mic_array") { - audio_sub_ = nh_.subscribe(params_.mobile_phone_topic.empty() - ? "/microphone_array/audio" - : "/microphone_array/audio", - 10, &AcousticNode::on_mic_array_audio, this); + audio_sub_ = nh_.subscribe("/microphone_array/audio", 10, + &AcousticNode::on_mic_array_audio, this); } else if (source_type_ == "mobile_phone") { audio_sub_ = nh_.subscribe(params_.mobile_phone_topic, 10, &AcousticNode::on_mobile_phone_audio, this); @@ -122,33 +115,37 @@ private: } } + // Convert multi-channel vector-of-vectors to flat interleaved format + std::vector flatten_audio(const std::vector>& audio, int channels) { + if (audio.empty() || channels == 0) return {}; + size_t samples = audio[0].size(); + std::vector flat(samples * channels); + for (size_t s = 0; s < samples; ++s) { + for (int ch = 0; ch < channels; ++ch) { + flat[s * channels + ch] = (ch < static_cast(audio.size()) && s < audio[ch].size()) + ? audio[ch][s] : 0.0f; + } + } + return flat; + } + void on_mic_array_audio(const std_msgs::Float32MultiArray::ConstPtr& msg) { - // Parse layout from dim: [channels, samples] if (msg->layout.dim.size() < 2) return; - int channels = msg->layout.dim[0].size; - int samples = msg->layout.dim[1].size; + int channels = static_cast(msg->layout.dim[0].size); + int samples = static_cast(msg->layout.dim[1].size); if (channels == 0 || samples == 0) return; - std::vector> audio(channels, std::vector(samples)); - for (int ch = 0; ch < channels; ++ch) { - for (int s = 0; s < samples; ++s) { - audio[ch][s] = msg->data[ch * samples + s]; - } - } - - std::vector threats; - if (channels == 1) { - pipeline_->process_single_channel(audio[0], threats); - } else { - pipeline_->process(audio, threats); - } - // Publish threats via threat_publisher (would be called by main loop) + // Assuming data is interleaved or [channels x samples] row-major + std::vector flat(msg->data.begin(), msg->data.end()); + auto frame = pipeline_->Process(flat); + (void)frame; // Would be published by threat_publisher in main loop } void on_mobile_phone_audio(const std_msgs::Float32MultiArray::ConstPtr& msg) { if (msg->data.empty()) return; - std::vector threats; - pipeline_->process_single_channel(msg->data, threats); + std::vector flat(msg->data.begin(), msg->data.end()); + auto frame = pipeline_->Process(flat); + (void)frame; } void process_wav_source() { @@ -161,12 +158,9 @@ private: ros::shutdown(); return; } - std::vector threats; - if (wav_source_->num_channels() == 1) { - pipeline_->process_single_channel(audio[0], threats); - } else { - pipeline_->process(audio, threats); - } + auto flat = flatten_audio(audio, static_cast(wav_source_->num_channels())); + auto frame = pipeline_->Process(flat); + (void)frame; } }; diff --git a/src/drone-software/src/acoustic/src/ros/threat_publisher.cpp b/src/drone-software/src/acoustic/src/ros/threat_publisher.cpp index 153dc39..4c78008 100644 --- a/src/drone-software/src/acoustic/src/ros/threat_publisher.cpp +++ b/src/drone-software/src/acoustic/src/ros/threat_publisher.cpp @@ -3,16 +3,26 @@ namespace acoustic { -ThreatPublisher::ThreatPublisher(ros::NodeHandle& nh) { - pub_ = nh.advertise("/acoustic/threats", 10); +struct ThreatPublisher::Impl { + ros::Publisher pub_; + std::size_t num_published_ = 0; +}; + +ThreatPublisher::ThreatPublisher(ros::NodeHandle& nh, const std::string& topic) + : impl_(std::make_unique()) { + impl_->pub_ = nh.advertise(topic, 10); } -void ThreatPublisher::publish(const std::vector& threats) { +ThreatPublisher::~ThreatPublisher() = default; +ThreatPublisher::ThreatPublisher(ThreatPublisher&&) noexcept = default; +ThreatPublisher& ThreatPublisher::operator=(ThreatPublisher&&) noexcept = default; + +void ThreatPublisher::Publish(const AcousticFrame& frame) { acoustic_analyzer::AcousticThreatArray msg; msg.header.stamp = ros::Time::now(); msg.header.frame_id = "acoustic_array"; - for (const auto& t : threats) { + for (const auto& t : frame.threats) { acoustic_analyzer::AcousticThreat threat_msg; threat_msg.threat_id = t.threat_id; threat_msg.sound_type = t.sound_type; @@ -24,7 +34,12 @@ void ThreatPublisher::publish(const std::vector& threats) { msg.threats.push_back(threat_msg); } - pub_.publish(msg); + impl_->pub_.publish(msg); + ++impl_->num_published_; +} + +std::size_t ThreatPublisher::NumPublished() const noexcept { + return impl_->num_published_; } } // namespace acoustic