Initial commit

main
邵朱铭 3 days ago
parent 1799c1c712
commit f5cca79319

@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(source /opt/rk3506-toolchain/environment-setup)",
"Bash(java -jar fastddsgen.jar lib/System.idl -d lib/ -replace)",
"Bash(make)"
]
}
}

@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 19.0.2, 2026-07-27T15:03:19. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{834c89b2-b6a0-49f4-8777-82ca3f17a41d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">false</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">10</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
<value type="int" key="RcSync">0</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="bool" key="HasPerBcDcs">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.11.1 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.11.1 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6111.win64_mingw_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Release</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_GENERATOR:STRING=MinGW Makefiles
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtcreator/cmake-helper/qtcreator-project.cmake
-DQT_CREATOR_ENABLE_MAINTENANCE_TOOL_PROVIDER:BOOL=ON
-DQT_CREATOR_ENABLE_PACKAGE_MANAGER_SETUP:BOOL=ON
-DQT_ENABLE_QML_DEBUG:BOOL=%{Qt:QT_ENABLE_QML_DEBUG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">.\build\%{Asciify:%{Kit:FileSystemName}-%{BuildConfig:Name}}</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString"></value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Install Application Manager package</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings">
<value type="bool" key="AndroidBuildTargetDirSupport">false</value>
<valuelist type="QVariantList" key="ApplicationmanagerPackageTargets"/>
<value type="bool" key="UseAndroidBuildTargetDir">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString"></value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Install Application Manager package</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

@ -30,7 +30,7 @@ include_directories(common)
include_directories(lib) include_directories(lib)
message(STATUS "Configuring System...") message(STATUS "Configuring System...")
add_library(System_lib lib/SystemTypeObjectSupport.cxx lib/SystemPubSubTypes.cxx) add_library(System_lib lib/WeighingDDSTypeTypeObjectSupport.cxx lib/WeighingDDSTypePubSubTypes.cxx)
target_link_libraries(System_lib fastcdr fastdds) target_link_libraries(System_lib fastcdr fastdds)
# Demo Application. # Demo Application.
@ -52,6 +52,8 @@ add_executable(Core
core/main.cxx core/main.cxx
core/Publisher.cxx core/Publisher.cxx
core/Subscriber.cxx core/Subscriber.cxx
core/msg.hpp
lib/WeighingDDSType.hpp
) )
target_compile_definitions(Core PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}") target_compile_definitions(Core PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(Core PRIVATE core) target_include_directories(Core PRIVATE core)
@ -104,16 +106,18 @@ target_link_libraries(HttpServer fastcdr fastdds
) )
# Led Application. # Led Application.
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib) # vendor SDKlibfun.so / YQNetCom.h TCP BX-6K1-YY
set(PROGRAM_MODULE "Led") set(PROGRAM_MODULE "Led")
add_executable(Led add_executable(Led
led/main.cxx led/main.cxx
led/Subscriber.cxx led/Subscriber.cxx
led/BX6K1YYProtocol.cxx
led/Bx6k1YyLedClient.cxx
) )
target_compile_definitions(Led PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}") target_compile_definitions(Led PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(Led PRIVATE led) target_include_directories(Led PRIVATE led)
target_link_libraries(Led fastcdr fastdds target_link_libraries(Led fastcdr fastdds
System_lib fun System_lib
) )
# Print Application. # Print Application.
@ -125,6 +129,7 @@ add_executable(Print
print/MsgHandler.cxx print/MsgHandler.cxx
common/SerialMsgHandler.cxx common/SerialMsgHandler.cxx
lib/strcode.cpp lib/strcode.cpp
print/MsgHandler.hpp
) )
target_compile_definitions(Print PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}") target_compile_definitions(Print PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(Print PRIVATE print) target_include_directories(Print PRIVATE print)
@ -132,6 +137,24 @@ target_link_libraries(Print fastcdr fastdds
System_lib System_lib
) )
# ReadCard Application.
set(PROGRAM_MODULE "ReadCard")
add_executable(ReadCard
readcard/main.cxx
readcard/Publisher.cxx
readcard/Subscriber.cxx
readcard/MsgHandler.cxx
readcard/Publisher.hpp
readcard/msg.hpp
common/SerialMsgHandler.cxx
readcard/MsgHandler.hpp
)
target_compile_definitions(ReadCard PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(ReadCard PRIVATE readcard)
target_link_libraries(ReadCard fastcdr fastdds
System_lib
)
# Weigh Application. # Weigh Application.
set(PROGRAM_MODULE "Weigh") set(PROGRAM_MODULE "Weigh")
add_executable(Weigh add_executable(Weigh
@ -141,6 +164,7 @@ add_executable(Weigh
weigh/MsgHandler.cxx weigh/MsgHandler.cxx
weigh/WeightStabilityDetector.cxx weigh/WeightStabilityDetector.cxx
common/SerialMsgHandler.cxx common/SerialMsgHandler.cxx
common/SerialMsgHandler.hpp
) )
target_compile_definitions(Weigh PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}") target_compile_definitions(Weigh PRIVATE PROGRAM_MODULE="${PROGRAM_MODULE}" PROGRAM_VERSION="${PROGRAM_VERSION}")
target_include_directories(Weigh PRIVATE weigh) target_include_directories(Weigh PRIVATE weigh)

@ -0,0 +1,666 @@
//#include "intrins.h"
#include "main.h"
#include "RC522.h"
#include "stdio.h"
//#include "tim.h"
extern TIM_HandleTypeDef htim6;
#define MAXRLEN 18
/////////////////////////////////////////////////////////////////////
#define RC522_RST_HIGH HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); //任意未接IO
#define RC522_RST_LOW HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); //任意未接IO
#define RC522_ENABLE HAL_GPIO_WritePin(ADDR_ALE_GPIO_Port,ADDR_ALE_Pin,GPIO_PIN_RESET);
#define RC522_DISABLE HAL_GPIO_WritePin(ADDR_ALE_GPIO_Port,ADDR_ALE_Pin,GPIO_PIN_SET);
extern SPI_HandleTypeDef hspi1;
#define fac_us 25 //72 //时钟频率单位MHZ
/*微秒级延时函数*/
//void delay_us(uint32_t nus)
//{
// uint32_t ticks;
// uint32_t told,tnow,tcnt=0;
// uint32_t reload=SysTick->LOAD; //LOAD的值
// ticks=nus*fac_us; //需要的节拍数
//// delay_osschedlock(); //阻止os调度防止打断us延时
//// vTaskSuspendAll();
// told=SysTick->VAL; //刚进入时的计数器值
// while(1)
// {
//
// tnow=SysTick->VAL;
// if(tnow!=told)
// {
// if(tnow<told) tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
// else tcnt+=reload-tnow+told;
// told=tnow;
// if(tcnt>=ticks) //时间超过/等于要延迟的时间,则退出.
// {
// break;
// }
// }
// }
//// delay_osschedunlock(); //恢复os调度
//// xTaskResumeAll(); //恢复OS调度
//}
void delay_us(uint16_t nus)
{
__HAL_TIM_SetCounter(&htim6,0);
__HAL_TIM_ENABLE(&htim6);
while(__HAL_TIM_GetCounter(&htim6)<nus);
__HAL_TIM_DISABLE(&htim6);
}
//----------------------------------------------------------------------------
int32_t SPI_WriteNBytes(SPI_TypeDef* SPIx, uint8_t *p_TxData,uint32_t sendDataNum)
{
uint16_t retry=0;
while(sendDataNum--){
while((SPIx->SR&SPI_FLAG_TXE)==0)//等待发送区空
{
retry++;
if(retry>20000)return -1;
}
SPIx->DR=*p_TxData++;//发送一个byte
retry=0;
while((SPIx->SR&SPI_FLAG_RXNE)==0)//等待接收完一个byte
{
SPIx->SR = SPIx->SR;
retry++;
if(retry>20000)return -1;
}
SPIx->DR;
}
return 0;
}
//------------------------------------------------------------------------------------
int32_t SPI_ReadNBytes(SPI_TypeDef* SPIx, uint8_t *p_RxData,uint32_t readDataNum)
{
uint16_t retry=0;
while(readDataNum--)
{
SPIx->DR = 0xFF;
while(!(SPIx->SR&SPI_FLAG_TXE))
{
retry++;
if(retry>20000)return -1;
}
retry = 0;
while(!(SPIx->SR&SPI_FLAG_RXNE))
{
retry++;
if(retry>20000)return -1;
}
*p_RxData++ = SPIx->DR;
}
return 0;
}
//------------------------------------------------------------------------------------
void RC522_Init(void)
{
RC522_ENABLE;
HAL_SPI_Transmit(&hspi1, (uint8_t *)0xaa, sizeof((uint8_t *)0xaa), 0xFF);//启动传输
RC522_DISABLE;
HAL_Delay(50);
PcdReset();//复位RC522读卡器
HAL_Delay(10);
PcdReset();//复位RC522读卡器
HAL_Delay(10);
PcdAntennaOff();//关闭天线发射
HAL_Delay(10);
PcdAntennaOn();//开启天线发射
printf("RFID-MFRC522 初始化完成\r\n"); //测试引脚初始化完成
// printf("RFID-MFRC522 Initialization Finished!\r\n"); //测试引脚初始化完成
printf("FindCard Starting ...\r\n"); //测试引脚初始化完成
}
//-------------------------------------------------------------------------------
//功 能:寻卡
//参数说明: req_code[IN]:寻卡方式
// 0x52 = 寻感应区内所有符合14443A标准的卡
// 0x26 = 寻未进入休眠状态的卡
// pTagType[OUT]:卡片类型代码
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
//返 回: 成功返回MI_OK
char PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg, 0x08); //清RC522寄存位
WriteRawRC(BitFramingReg, 0x07); //写RC623寄存器
SetBitMask(TxControlReg, 0x03); //置RC522寄存位
ucComMF522Buf[0] = req_code;
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf, &unLen);
if ((status == MI_OK) && (unLen == 0x10))
{
*pTagType = ucComMF522Buf[0];
*(pTagType + 1) = ucComMF522Buf[1];
}
else
{
status = MI_ERR;
}
return status;
}
//-------------------------------------------------------------------------------
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号4字节
//返 回: 成功返回MI_OK
char PcdAnticoll(unsigned char *pSnr)
{
char status;
unsigned char i, snr_check = 0;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg, 0x08);
WriteRawRC(BitFramingReg, 0x00);
ClearBitMask(CollReg, 0x80);
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, &unLen);
if (status == MI_OK)
{
for (i = 0; i < 4; i++)
{
*(pSnr + i) = ucComMF522Buf[i];
snr_check ^= ucComMF522Buf[i];
}
if (snr_check != ucComMF522Buf[i])
{
status = MI_ERR;
}
}
SetBitMask(CollReg, 0x80);
return status;
}
//---------------------------------------------------------------------------
//功 能:选定卡片
//参数说明: pSnr[IN]:卡片序列号4字节
//返 回: 成功返回MI_OK
char PcdSelect(unsigned char *pSnr)
{
char status;
unsigned char i;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i = 0; i < 4; i++)
{
ucComMF522Buf[i + 2] = *(pSnr + i);
ucComMF522Buf[6] ^= *(pSnr + i);
}
CalulateCRC(ucComMF522Buf, 7, &ucComMF522Buf[7]);
ClearBitMask(Status2Reg, 0x08);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf, &unLen);
if ((status == MI_OK) && (unLen == 0x18))
{
status = MI_OK;
}
else
{
status = MI_ERR;
}
return status;
}
//----------------------------------------------------------------------------------
//功 能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
// 0x60 = 验证A密钥
// 0x61 = 验证B密钥
// addr[IN]:块地址
// pKey[IN]:密码
// pSnr[IN]卡片序列号4字节
//返 回: 成功返回MI_OK
char PcdAuthState(unsigned char auth_mode, unsigned char addr, unsigned char *pKey, unsigned char *pSnr)
{
char status;
unsigned int unLen;
unsigned char i, ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = auth_mode;
ucComMF522Buf[1] = addr;
for (i = 0; i < 6; i++)
{
ucComMF522Buf[i + 2] = *(pKey + i);
}
for (i = 0; i < 6; i++)
{
ucComMF522Buf[i + 8] = *(pSnr + i);
}
status = PcdComMF522(PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
{
status = MI_ERR;
}
return status;
}
//--------------------------------------------------------------------------------------
//功 能读取M1卡一块数据
//参数说明: addr[IN]:块地址
// p [OUT]读出的数据16字节
//返 回: 成功返回MI_OK
char PcdRead(unsigned char addr, unsigned char *pData)
{
char status;
unsigned int unLen;
unsigned char i, ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_READ;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status == MI_OK) && (unLen == 0x90))
{
for (i = 0; i < 16; i++)
{
*(pData + i) = ucComMF522Buf[i];
}
}
else
{
status = MI_ERR;
}
return status;
}
//-----------------------------------------------------------------------------------
//功 能写数据到M1卡一块
//参数说明: addr[IN]:块地址
// p [IN]写入的数据16字节
//返 回: 成功返回MI_OK
char PcdWrite(unsigned char addr, unsigned char *pData)
{
char status;
unsigned int unLen;
unsigned char i, ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_WRITE;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
if (status == MI_OK)
{
for (i = 0; i < 16; i++)
{
ucComMF522Buf[i] = *(pData + i);
}
CalulateCRC(ucComMF522Buf, 16, &ucComMF522Buf[16]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
}
return status;
}
//----------------------------------------------------------------------------------
//功 能:扣款和充值
//参数说明: dd_mode[IN]:命令字
// 0xC0 = 扣款
// 0xC1 = 充值
// addr[IN]:钱包地址
// pValue[IN]4字节增(减)值,低位在前
//返 回: 成功返回MI_OK
char PcdValue(unsigned char dd_mode, unsigned char addr, unsigned char *pValue)
{
char status;
unsigned int unLen;
unsigned char i, ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = dd_mode;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
if (status == MI_OK)
{
for (i = 0; i < 16; i++)
{
ucComMF522Buf[i] = *(pValue + i);
}
CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
unLen = 0;
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
if (status != MI_ERR)
{
status = MI_OK;
}
}
if (status == MI_OK)
{
ucComMF522Buf[0] = PICC_TRANSFER;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
}
return status;
}
//------------------------------------------------------------------------------------
//功 能:备份钱包
//参数说明: sourceaddr[IN]:源地址
// goaladdr[IN]:目标地址
//返 回: 成功返回MI_OK
char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
{
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_RESTORE;
ucComMF522Buf[1] = sourceaddr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
if (status == MI_OK)
{
ucComMF522Buf[0] = 0;
ucComMF522Buf[1] = 0;
ucComMF522Buf[2] = 0;
ucComMF522Buf[3] = 0;
CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
if (status != MI_ERR)
{
status = MI_OK;
}
}
if (status != MI_OK)
{
return MI_ERR;
}
ucComMF522Buf[0] = PICC_TRANSFER;
ucComMF522Buf[1] = goaladdr;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
return status;
}
//------------------------------------------------------------------------------------
//功 能:命令卡片进入休眠状态
//返 回: 成功返回MI_OK
char PcdHalt(void)
{
// char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_HALT;
ucComMF522Buf[1] = 0;
CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);
PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
return MI_OK;
}
//--------------------------------------------------------------------------------------
//用MF522计算CRC16函数
void CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
{
unsigned char i, n;
ClearBitMask(DivIrqReg, 0x04);
WriteRawRC(CommandReg, PCD_IDLE);
SetBitMask(FIFOLevelReg, 0x80);
for (i = 0; i < len; i++)
{
WriteRawRC(FIFODataReg, *(pIndata + i));
}
WriteRawRC(CommandReg, PCD_CALCCRC);
i = 0xFF;
do
{
n = ReadRawRC(DivIrqReg);
i--;
} while ((i != 0) && !(n & 0x04));
pOutData[0] = ReadRawRC(CRCResultRegL);
pOutData[1] = ReadRawRC(CRCResultRegM);
}
//-----------------------------------------------------------------------------------------
//功 能复位RC522
//返 回: 成功返回MI_OK
char PcdReset(void)
{
// RC522_RST_HIGH;
// delay_us(10);
// RC522_RST_LOW;
// HAL_Delay(60);
// RC522_RST_HIGH;
// HAL_GPIO_WritePin(LED_RUN_GPIO_Port,LED_RUN_Pin,GPIO_PIN_RESET);
delay_us(4000);
WriteRawRC(CommandReg, PCD_RESETPHASE);
HAL_Delay(20);
WriteRawRC(ModeReg, 0x3D);
WriteRawRC(TReloadRegL, 30);
WriteRawRC(TReloadRegH, 0);
WriteRawRC(TModeReg, 0x8D);
WriteRawRC(TPrescalerReg, 0x3E);
WriteRawRC(TxAutoReg, 0x40);
ClearBitMask(TestPinEnReg, 0x80);
WriteRawRC(TxAutoReg, 0x40);
return MI_OK;
}
//-------------------------------------------------------------------------------------
//功 能读RC632寄存器
//参数说明Address[IN]:寄存器地址
//返 回:读出的值
unsigned char ReadRawRC(unsigned char Address)
{
unsigned char ucAddr;
unsigned char ucResult = 0;
ucAddr = ((Address << 1) & 0x7E) | 0x80;
HAL_Delay(10);
RC522_ENABLE;
SPI_WriteNBytes(SPI1, &ucAddr, 1); //向总线写多个数据
SPI_ReadNBytes(SPI1, &ucResult, 1); //向总线读多个数据
// HAL_SPI_Transmit(&hspi1,&ucAddr,1,0xff);
// HAL_SPI_Receive(&hspi1,&ucResult,1,0xff);
// while(HAL_SPI_Transmit(&hspi1,&ucAddr,1,0xff) == HAL_OK);
// while(HAL_SPI_Receive(&hspi1,&ucResult,1,0xff) == HAL_OK);
RC522_DISABLE;
return ucResult;
}
//---------------------------------------------------------------------------------------------
//功 能写RC632寄存器
//参数说明Address[IN]:寄存器地址
// value[IN]:写入的值
void WriteRawRC(unsigned char Address, unsigned char value)
{
unsigned char ucAddr;
uint8_t write_buffer[2] = {0};
ucAddr = ((Address << 1) & 0x7E);
write_buffer[0] = ucAddr;
write_buffer[1] = value;
HAL_Delay(10);
RC522_ENABLE;
SPI_WriteNBytes(SPI1, write_buffer, 2);
// HAL_SPI_Transmit(&hspi1,write_buffer,2,0xff);
// while(HAL_SPI_Transmit(&hspi1,write_buffer,2,0xff) == HAL_OK);
RC522_DISABLE;
}
//---------------------------------------------------------------------------------------------
//功 能置RC522寄存器位
//参数说明reg[IN]:寄存器地址
// mask[IN]:置位值
void SetBitMask(unsigned char reg, unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg); //读RC632寄存器
WriteRawRC(reg, tmp | mask); // set bit mask
}
//-----------------------------------------------------------------------------------------------
//功 能清RC522寄存器位
//参数说明reg[IN]:寄存器地址
// mask[IN]:清位值
void ClearBitMask(unsigned char reg, unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg, tmp & ~mask); // clear bit mask
}
//------------------------------------------------------------------------------------------
//功 能通过RC522和ISO14443卡通讯
//参数说明Command[IN]:RC522命令字
// pIn [IN]:通过RC522发送到卡片的数据
// InLenByte[IN]:发送数据的字节长度
// pOut [OUT]:接收到的卡片返回数据
// *pOutLenBit[OUT]:返回数据的位长度
char PcdComMF522(unsigned char Command,
unsigned char *pInData,
unsigned char InLenByte,
unsigned char *pOutData,
unsigned int *pOutLenBit)
{
char status = MI_ERR;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char lastBits;
unsigned char n;
unsigned int i;
switch (Command)
{
case PCD_AUTHENT:
irqEn = 0x12;
waitFor = 0x10;
break;
case PCD_TRANSCEIVE:
irqEn = 0x77;
waitFor = 0x30;
break;
default:
break;
}
WriteRawRC(ComIEnReg, irqEn | 0x80);
ClearBitMask(ComIrqReg, 0x80);
WriteRawRC(CommandReg, PCD_IDLE);
SetBitMask(FIFOLevelReg, 0x80);
for (i = 0; i < InLenByte; i++)
{
WriteRawRC(FIFODataReg, pInData[i]);
}
WriteRawRC(CommandReg, Command);
if (Command == PCD_TRANSCEIVE)
{
SetBitMask(BitFramingReg, 0x80);
}
i = 800; //根据时钟频率调整操作M1卡最大等待时间25ms
do
{
n = ReadRawRC(ComIrqReg);
i--;
} while ((i != 0) && !(n & 0x01) && !(n & waitFor));
ClearBitMask(BitFramingReg, 0x80);
if (i != 0)
{
if (!(ReadRawRC(ErrorReg) & 0x1B))
{
status = MI_OK;
if (n & irqEn & 0x01)
{
status = MI_NOTAGERR;
}
if (Command == PCD_TRANSCEIVE)
{
n = ReadRawRC(FIFOLevelReg);
lastBits = ReadRawRC(ControlReg) & 0x07;
if (lastBits)
{
*pOutLenBit = (n - 1) * 8 + lastBits;
}
else
{
*pOutLenBit = n * 8;
}
if (n == 0)
{
n = 1;
}
if (n > MAXRLEN)
{
n = MAXRLEN;
}
for (i = 0; i < n; i++)
{
pOutData[i] = ReadRawRC(FIFODataReg);
}
}
}
else
{
status = MI_ERR;
}
}
SetBitMask(ControlReg, 0x80); // stop timer now
WriteRawRC(CommandReg, PCD_IDLE);
return status;
}
//--------------------------------------------------------------------------------------
//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
void PcdAntennaOn(void)
{
unsigned char i;
i = ReadRawRC(TxControlReg);
if (!(i & 0x03))
{
SetBitMask(TxControlReg, 0x03);
}
}
//----------------------------------------------------------------------------------------
//关闭天线
void PcdAntennaOff(void)
{
ClearBitMask(TxControlReg, 0x03);
}
//------------------------------------------------
void RC522_Config(unsigned char Card_Type)
{
ClearBitMask(Status2Reg, 0x08);
WriteRawRC(ModeReg, 0x3D);
WriteRawRC(RxSelReg, 0x86);
WriteRawRC(RFCfgReg, 0x7F);
WriteRawRC(TReloadRegL, 30);
WriteRawRC(TReloadRegH, 0);
WriteRawRC(TModeReg, 0x8D);
WriteRawRC(TPrescalerReg, 0x3E);
HAL_Delay(5);
PcdAntennaOn();
}

@ -0,0 +1,532 @@
/*******************************************************************************
* User\src\RFID_S50.c
*
* V3.5.0
* V1.0
* 2016218
*
******************************************************************************
*
*
*
*
*
*
*
******************************************************************************/
#ifdef RFIDS50_DEV
#include "stm32f10x.h"
#include "RFID_S50.h"
#include <string.h>
#include <stdlib.h>
#include "FiveSuart.h"
#include "CANManager.h"
#define RFID_S50_CMD_Parameter 20 //0x14 串口参数设置
#define RFID_S50_CMD_Control 21 //0x15 控制设备 打开或关闭
#define RFID_S50_CMD_Beep 22 //0x16 蜂鸣
#define RFID_S50_CMD_Password 23 //0x17 下载密码
#define RFID_S50_CMD_FindCard 24 //0x18 自动寻卡
#define RFID_S50_CMD_ReadCard 25 //0x19 读卡
#define RFID_S50_CMD_WriteCard 26 //0x1A 写卡
#define RFID_S50_CMD_Stop 27 //0x1B 中止
#define RFID_S50_CMD_Reset 29 //0x1D 复位
RFID_S50_Parameter RFID_S50_Para;
//验证写卡包内容 modified by Hy 2019-10-20
uint8_t RFID_S50_CheckedData[16]={0};
//验证写卡块号 modified by Hy 2019-10-20
uint8_t RFID_S50_CheckedBlockID=0;
//是否写卡成功 modified by Hy 2019-10-20
bool isWrite=false;
//读卡 modified by Hy 2019-10-20
void ReadCard(uint8_t blockID)
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[6]={0};
m_buf[0] = 0x05; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x04; //命令号
m_buf[3] = blockID; //块号
crcResult = CRC16(m_buf, 4);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[4] = crcH;
m_buf[5] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,6);
}
/*******************************************************************************
* Function Name : RFID_S50_OnCommand
* Description :
* Input : data
* Output : None
* Return : None
* Attention :
*******************************************************************************/
void RFID_S50_OnCommand(uint8_t * pData ,uint16_t m_len )
{
//已收到全部数据
if (pData[1] == 1)
{
//如果地址等于1
uint16_t crcResult = 0; //校验结果
uint8_t crcL = 0; //校验低位
uint8_t crcH = 0; //校验高位
crcResult = CRC16(pData,m_len - 2);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
//if ((crcL == pData[m_len - 1]) || (crcH == pData[m_len]))
if ((crcH == pData[m_len - 2]) && (crcL == pData[m_len-1]))
{
//通过校验
uint8_t m_Command = pData[2]; //命令号
if (pData[3]==0)
{
//如果返回正常
CanTxMsg TxMsg;
TxMsg.RTR = CAN_RTR_DATA; // 设置为数据帧
TxMsg.IDE = CAN_ID_EXT; // 使用扩展帧
switch (m_Command)
{
case 1: //蜂鸣
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_Beep,0x01);
//返回成功信息
CAN_SendResult(m_id,0x00);
}
break;
case 2: //寻卡返回
{
TxMsg.ExtId=GetCANID(DeviceID,RFID_S50_CMD_FindCard,0x01);
TxMsg.DLC=5;
TxMsg.Data[0]=0x00;
TxMsg.Data[1]=pData[4];
TxMsg.Data[2]=pData[5];
TxMsg.Data[3]=pData[6];
TxMsg.Data[4]=pData[7];
CAN_SendData(&TxMsg);
}
break;
case 3: //下载密码
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_Password,0x01);
//返回成功信息
CAN_SendResult(m_id,0x00);
}
break;
case 4: //读数据块返回
{
int flag = 0;
int i = 0;
//验证包内容 modified by Hy 2019-10-20
if(isWrite)
{
isWrite=false;
if(RFID_S50_CheckedBlockID==pData[4])
{
for (i = 0; i < 16; i++)
{
if (RFID_S50_CheckedData[i] != pData[i+5])
{
flag = 1;
break;
}
}
if (flag == 1)
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_WriteCard,0x01);
//返回失败信息
CAN_SendResult(m_id,0x01);
}
else
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_WriteCard,0x01);
//返回成功信息
CAN_SendResult(m_id,0x00);
}
}
}
else
{
//正确返回1个字节的块号和16个字节数据
TxMsg.ExtId=GetCANID(DeviceID,RFID_S50_CMD_ReadCard,0x01);
TxMsg.DLC=2;
TxMsg.Data[0]=0x00;
TxMsg.Data[1]=pData[4];
CAN_SendData(&TxMsg);
TxMsg.ExtId=GetCANID(DeviceID,RFID_S50_CMD_ReadCard,0x02);
TxMsg.DLC=8;
TxMsg.Data[0]=pData[5];
TxMsg.Data[1]=pData[6];
TxMsg.Data[2]=pData[7];
TxMsg.Data[3]=pData[8];
TxMsg.Data[4]=pData[9];
TxMsg.Data[5]=pData[10];
TxMsg.Data[6]=pData[11];
TxMsg.Data[7]=pData[12];
CAN_SendData(&TxMsg);
TxMsg.ExtId=GetCANID(DeviceID,RFID_S50_CMD_ReadCard,0x03);
TxMsg.DLC=8;
TxMsg.Data[0]=pData[13];
TxMsg.Data[1]=pData[14];
TxMsg.Data[2]=pData[15];
TxMsg.Data[3]=pData[16];
TxMsg.Data[4]=pData[17];
TxMsg.Data[5]=pData[18];
TxMsg.Data[6]=pData[19];
TxMsg.Data[7]=pData[20];
CAN_SendData(&TxMsg);
}
}
break;
case 5: //写卡
{
//写卡成功后读卡 modified by Hy 2019-10-20
isWrite=true;
ReadCard(RFID_S50_CheckedBlockID);
}
break;
case 8: //中止IC卡
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_Stop,0x01);
//返回成功信息
CAN_SendResult(m_id,0x00);
}
break;
}
}
else
{
//如果返回失败
CanTxMsg TxMsg;
TxMsg.RTR = CAN_RTR_DATA; // 设置为数据帧
TxMsg.IDE = CAN_ID_EXT; // 使用扩展帧
switch (m_Command)
{
case 4: //读数据块返回
{
//获取CANID
TxMsg.ExtId=GetCANID(DeviceID,RFID_S50_CMD_ReadCard,0x01);
TxMsg.DLC=3;
TxMsg.Data[0]=0x01;
TxMsg.Data[1]=pData[3];
TxMsg.Data[2]=pData[4];
CAN_SendData(&TxMsg);
}
}
}
}//校验
}
else
{
//地址不准确,无需返回
RFID_S50_Reset();
}
}
//当收到串口数据
void RFID_S50_OnData(uint8_t * m_buf,int m_len)
{
int m_idx=0;
uint8_t temp;
for (m_idx=0;m_idx<m_len;m_idx++)
{
temp=m_buf[m_idx];
if (RFID_S50_Para.IndexFlag==0)
{
//先读出长度
RFID_S50_Para.Index=0;
RFID_S50_Para.DataLen=temp; //长度
RFID_S50_Para.Data[RFID_S50_Para.Index] =temp;
RFID_S50_Para.Index++;
RFID_S50_Para.IndexFlag=1;
}
else if (RFID_S50_Para.IndexFlag==1)
{
//读取后续数据
RFID_S50_Para.Data[RFID_S50_Para.Index] = temp;
RFID_S50_Para.Index++;
//执行命令
if (RFID_S50_Para.Index == RFID_S50_Para.DataLen+1)
{
//处理返回的结果
RFID_S50_OnCommand(RFID_S50_Para.Data,RFID_S50_Para.DataLen+1);
RFID_S50_Para.IndexFlag=0;
}
}
}
}
void RFID_S50_Process()
{
}
uint8_t RFID_S50_ProcessData[18]={0};
bool RFID_S50_OnCANData(CanBlock * RxMsg)
{
bool bResult=false;
uint32_t iTemp=0;
switch(RxMsg->CommandID)
{
case RFID_S50_CMD_Parameter: //0x14 设置串口参数
{
RFID_S50_Reset();
RFID_S50_Para.Times=1; //设置超时时间
RFID_S50_Para.CommPara.USARTID =RxMsg->Value[0]; //串口号
RFID_S50_Para.CommPara.BaudRate =RxMsg->Value[1]; //波特率
RFID_S50_Para.CommPara.WordLength =RxMsg->Value[2]; //数据位
RFID_S50_Para.CommPara.StopBits =RxMsg->Value[3]; //停止位
RFID_S50_Para.CommPara.Parity =RxMsg->Value[4]; //校验位
RFID_S50_Para.Type =RxMsg->Value[5]; //读卡器种类
iTemp=GetCANID(DeviceID,0x14,0x01);
CAN_SendResult(iTemp,00);
bResult=true;
}
break;
case RFID_S50_CMD_Control: //0x15 控制设备
{
if (RxMsg->Value[0]==1)
{
//打开设备
//1、打开串口
//2、将当前设备接收函数挂接到串口上
uint32_t tmp_BaudRate=GetBaudRate(RFID_S50_Para.CommPara.BaudRate);
uint16_t tmp_Parity =GetParity(RFID_S50_Para.CommPara.Parity);
Usart_Open(RFID_S50_Para.CommPara.USARTID,tmp_BaudRate,RFID_S50_Para.CommPara.WordLength,RFID_S50_Para.CommPara.StopBits,tmp_Parity);
SetDeviceOnData(RFID_S50_Para.CommPara.USARTID,RFID_S50_OnData);
SetDeviceProcess(RFID_S50_Para.CommPara.USARTID,RFID_S50_Process);
//TIM2_Configuration(Weight_Times*2000); //超时2秒
//TIM_Cmd(TIM2, ENABLE); //打开超时时钟
iTemp=GetCANID(DeviceID,RFID_S50_CMD_Control,0x01);
CAN_SendResult(iTemp,00);
RFID_S50_Para.Open=true;
}
else if (RxMsg->Value[0]==0)
{
//关闭设备
}
bResult=true;
}
break;
case RFID_S50_CMD_Beep: //蜂鸣
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[6]={0};
if (!RFID_S50_Para.Open)
return false;
m_buf[0] = 0x05; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x01; //命令号
m_buf[3] = 0x0F; //蜂鸣时间
crcResult = CRC16(m_buf, 4);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[4] = crcH; //0xBC
m_buf[5] = crcL; //0x10
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,6);
bResult=true;
}
break;
case RFID_S50_CMD_Password : // 22 下载密码 0x16
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[13]={0};
m_buf[0] = 0x0C; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x03; //命令号
memcpy(m_buf+3,RxMsg->Value,8); //CAN 8个字节
crcResult = CRC16(m_buf,11);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[11] = crcH;
m_buf[12] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,13);
bResult=true;
}
break;
case RFID_S50_CMD_FindCard : // 23 自动寻卡 0x18
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[5]={0};
if (!RFID_S50_Para.Open)
return false;
m_buf[0] = 0x04; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x02; //命令 寻卡
crcResult = CRC16(m_buf, 3);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[3] = crcH;
m_buf[4] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,5);
bResult=true;
}
break;
case RFID_S50_CMD_ReadCard : // 24 读卡 0x19
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[6]={0};
if (!RFID_S50_Para.Open)
return false;
m_buf[0] = 0x05; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x04; //命令号
m_buf[3] = RxMsg->Value[0]; //块号
crcResult = CRC16(m_buf, 4);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[4] = crcH;
m_buf[5] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,6);
bResult=true;
}
break;
case RFID_S50_CMD_WriteCard : // 25 写卡 0x19
{
if (RxMsg->BlockID==1)
{
//第一包
RFID_S50_ProcessData[0]=RxMsg->Value[0];
RFID_S50_CheckedBlockID=RxMsg->Value[0];
}
else if (RxMsg->BlockID==2)
{
//第二包
memcpy(RFID_S50_ProcessData+1,RxMsg->Value,8);
}
else if (RxMsg->BlockID==3)
{
//第三包
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[22]={0};
if (!RFID_S50_Para.Open)
return false;
memcpy(RFID_S50_ProcessData+9,RxMsg->Value,8);
m_buf[0] = 0x15; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x05; //命令号
memcpy(m_buf+3,RFID_S50_ProcessData,17); //CAN 17个字节
crcResult = CRC16(m_buf,20);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[20] = crcH;
m_buf[21] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,22);
//保存写卡时所发包内容 modified by Hy 2019-10-20
memcpy(RFID_S50_CheckedData,RFID_S50_ProcessData+1,16);
}
bResult=true;
}
break;
case RFID_S50_CMD_Stop: //中止卡
{
uint16_t crcResult=0;
uint8_t crcL=0;
uint8_t crcH=0;
uint8_t m_buf[5]={0};
if (!RFID_S50_Para.Open)
return false;
m_buf[0] = 0x04; //长度
m_buf[1] = 0x01; //地址
m_buf[2] = 0x08; //命令
crcResult = CRC16(m_buf, 3);
crcL = (uint8_t)(crcResult & 0xFF);
crcH = (uint8_t)(crcResult >> 8);
m_buf[3] = crcH;
m_buf[4] = crcL;
Usart_SendData(RFID_S50_Para.CommPara.USARTID,m_buf,5);
bResult=true;
}
break;
case RFID_S50_CMD_Reset:
{
uint32_t m_id=GetCANID(DeviceID,RFID_S50_CMD_Reset,0x01);
//返回成功信息
CAN_SendResult(m_id,0x00);
RFID_S50_Reset();
bResult=true;
}
break;
}
return bResult;
}
// void TIM3_IRQHandler(void)
// {
// if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
// {
// TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
// }
// }
//复位
void RFID_S50_Reset()
{
RFID_S50_Para.IndexFlag=0;
}
#endif

@ -0,0 +1,78 @@
#! /bin/sh
# Load default env variables from profiles(e.g. /etc/profile.d/*.sh)
. /etc/profile
start_app()
{
# Wait for weston ready, 5 seconds timeout
counter=0
while [ ! -e "${XDG_RUNTIME_DIR}/wayland-0" ] && [ $counter -lt 50 ]; do
sleep 0.1
counter=$((counter + 1))
done
if wait_for_network; then
killall weston 2>/dev/null || true
sleep 0.5
/userdata/auseft/WeighUI --domain 13 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/device-daemon > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/Core --domain 13 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/IoCtrl --device gpio --device_id 1 --domain 13 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/HttpServer --domain 13 --port 8081 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/Print --domain 13 --port ttyS2 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/MqttDds --domain 13 --addr ws://10.180.4.1:8083 --user auseft --password 1q2w3E** > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/Led --domain 13 --type 1 --addr 192.168.6.147 > /dev/null 2>&1 &
sleep 0.5
/userdata/auseft/ReadCard --domain 13 > /dev/null 2>&1 &
else
echo "network failed."
fi
}
wait_for_network()
{
local interface="eth0"
local retries=50
local count=0
echo "wait network $interface start..."
while [ $count -lt $retries ]; do
if ip link show $interface | grep -q "state UP"; then
echo "$interface started."
return 0
fi
sleep 1
count=$((count + 1))
done
echo "network $interface start failed, retry $retries times."
return 1
}
case $1 in
start)
#sh /oem/RkLunch.sh
ip link set can0 type can bitrate 500000 dbitrate 1000000 fd on
ip link set up can0
echo 34 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio34/direction
echo 1 > /sys/class/gpio/gpio34/value
# start_app
;;
stop)
#sh /oem/RkLunch-stop.sh
;;
*)
echo "Usage: $0 {start|stop}"
;;
esac

@ -83,6 +83,8 @@ bool CanMsgHandler::OpenPort(const std::string& port, const std::string& baudrat
// return false; // return false;
// } // }
return true; return true;
} }

@ -23,6 +23,8 @@ bool SerialMsgHandler::OpenPort(const std::string &port, const std::string &baud
ClosePort(); ClosePort();
fd = open(tty.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); fd = open(tty.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) if (fd == -1)
{ {
@ -51,16 +53,31 @@ bool SerialMsgHandler::OpenPort(const std::string &port, const std::string &baud
if (baudrate == "115200") if (baudrate == "115200")
{ {
baund = B115200; baund = B115200;
} }
else if (baudrate == "9600") else if (baudrate == "9600")
{ {
baund = B9600; baund = B9600;
}
else if (baudrate == "19200")
{
baund = B19200;
}
else if (baudrate == "57600")
{
baund = B57600;
} }
else else
{ {
baund = B9600; baund = B9600;
} }
// ========== 新增:保存波特率 ==========
baudrate_ = baund;
return setPortAttributes(baund); return setPortAttributes(baund);
} }
@ -69,6 +86,10 @@ bool SerialMsgHandler::setPortAttributes(int baudrate)
{ {
struct termios options; struct termios options;
// ========== 新增:调试打印配置前的状态 ==========
std::cout << "[DEBUG] setPortAttributes: configuring port with baudrate=" << baudrate << std::endl;
// 获取当前串口设置 // 获取当前串口设置
if (tcgetattr(fd, &options) != 0) if (tcgetattr(fd, &options) != 0)
{ {
@ -116,3 +137,17 @@ bool SerialMsgHandler::setPortAttributes(int baudrate)
return true; return true;
} }
// ========== 新增:刷新串口配置 ==========
bool SerialMsgHandler::refreshPort()
{
if (fd == -1) {
std::cout << "[DEBUG] refreshPort: fd is -1, skip" << std::endl;
return false;
}
// ========== 调试打印 ==========
std::cout << "[DEBUG] refreshPort: reconfiguring port, baudrate=" << baudrate_ << std::endl;
return setPortAttributes(baudrate_);
}

@ -3,6 +3,8 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <iostream>
#include <termios.h>
#include "MsgHandler.hpp" #include "MsgHandler.hpp"
@ -18,7 +20,11 @@ public:
// 设置串口参数 // 设置串口参数
bool setPortAttributes(int baudrate); bool setPortAttributes(int baudrate);
bool refreshPort();
private: private:
speed_t baudrate_; // 新增保存波特率speed_t 类型)
}; };
#endif // _SERIALMSGHANDLER_HPP_ #endif // _SERIALMSGHANDLER_HPP_

@ -0,0 +1,89 @@
{
"dds":
{
"domain": 0
},
"mqtt":
{
"server_url": "mqtt://192.168.1.2:1883",
"client_id": "ddsmqtt_sub_pub_0",
"username": "admin",
"password": "admin",
"sub_topic": ["command"],
"sub_qos": [0],
"pub_topic": ["response"],
"pub_qos": [0]
},
"httpserver":
{
"port": 8080
},
"ioctrl":
{
"bus": "gpio",
"device": "gpio",
"iomap": {
"out": {
"frontbarrup": [48, 0],
"frontbardown": [49, 0]
},
"in": {
"frontdetect": [5, 1]
}
}
},
"led":
{
"ip": "192.168.0.199",
"port": 80,
"path": "/home/bo/project/app/dds/led/build/"
},
"print":
{
"bus": "serial",
"port": "ttyS2",
"baudrate": "9600",
"device": "NP80A"
},
"readcard":
{
"bus": "serial",
"port": "ttyS1",
"baudrate": "9600",
"device": "RC522",
"password":
[
{
"sector": 1,
"data": [1, 2, 3, 4, 5, 6]
},
{
"sector": 2,
"data": [7, 8, 9, 10, 11, 12]
},
{
"sector": 3,
"data": [13, 14, 15, 16, 17, 18]
},
{
"sector": 4,
"data": [19, 20, 21, 22, 23, 24]
},
{
"sector": 5,
"data": [25, 26, 27, 28, 29, 30]
},
{
"sector": 10,
"data": [177, 10, 35, 209, 143, 32]
}
]
},
"weigh":
{
"bus": "serial",
"port": "ttyS5",
"baudrate": "9600",
"device": "Keli"
}
}

@ -24,7 +24,10 @@
#include <condition_variable> #include <condition_variable>
#include <csignal> #include <csignal>
#include <stdexcept> #include <stdexcept>
#include <iomanip>
#include <chrono>
#include <thread> #include <thread>
#include <cmath> // 新增:用于 std::fabs
#include <fastdds/dds/domain/DomainParticipantFactory.hpp> #include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/log/Log.hpp> #include <fastdds/dds/log/Log.hpp>
@ -33,10 +36,11 @@
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> #include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp> #include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
using namespace eprosima::fastdds::dds; using namespace eprosima::fastdds::dds;
PublisherApp::PublisherApp( PublisherApp::PublisherApp(
@ -55,13 +59,11 @@ PublisherApp::PublisherApp(
, summary_type_(new WeighingSystem::SummaryUpdatePubSubType()) , summary_type_(new WeighingSystem::SummaryUpdatePubSubType())
, print_topic_(nullptr) , print_topic_(nullptr)
, print_writer_(nullptr) , print_writer_(nullptr)
, print_type_(new InternalSystem::PrintReqPubSubType()) , print_type_(new WeighingSystem::PrintReqPubSubType())
, matched_(0) , matched_(0)
, samples_sent_(0) , samples_sent_(0)
, stop_(false) , stop_(false)
{ {
//
// Create the participant // Create the participant
DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT; DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("Core_pub_participant"); pqos.name("Core_pub_participant");
@ -319,7 +321,7 @@ bool PublisherApp::light_ctrl(const std::map<std::string, std::string>& ctrl)
bool PublisherApp::print_receipt(const std::map<std::string, std::string>& msg) bool PublisherApp::print_receipt(const std::map<std::string, std::string>& msg)
{ {
InternalSystem::PrintReq req; WeighingSystem::PrintReq req;
req.msg() = msg; req.msg() = msg;
@ -334,162 +336,59 @@ bool PublisherApp::print_receipt(const std::map<std::string, std::string>& msg)
} }
#define WEIGH_IDLE 0 #define WEIGH_IDLE 0
#define WEIGH_LIC 1 #define WEIGH_QUEUE_RAISED 1 // 已抬杆,计时等 60s 落杆
#define WEIGH_STABLE1 2
#define WEIGH_STABLE2 3
#define WEIGH_SEND 4
#define WEIGH_PRINT 5
#define WEIGH_ERROR 6
#define WEIGH_LEAVE 7
void PublisherApp::run() void PublisherApp::run()
{ {
std::string license_no;
float stable_weight = 0;
float stable_weight1 = 0;
float stable_weight2 = 0;
int weigh_state = WEIGH_IDLE; int weigh_state = WEIGH_IDLE;
while (!is_stopped()) while (!is_stopped())
{ {
// 1) 消费 DDS 队列
std::unique_lock<std::mutex> dds_lock(DdsMsgData::queue_cv_mtx_, std::try_to_lock); std::unique_lock<std::mutex> dds_lock(DdsMsgData::queue_cv_mtx_, std::try_to_lock);
if (dds_lock.owns_lock()) if (dds_lock.owns_lock())
{ {
if (!DdsMsgData::LicenseSnapUpdate_queue_.empty()) if (!DdsMsgData::QueueSuccess_queue_.empty())
{
WeighingSystem::LicenseSnapUpdate info = std::move(DdsMsgData::LicenseSnapUpdate_queue_.front());
DdsMsgData::LicenseSnapUpdate_queue_.pop();
dds_lock.unlock();
DEBUG("车牌: " << info.License());
DEBUG("类型: " << info.NewTag());
if (license_no.empty() == true)
{
license_no = info.License();
weigh_state = WEIGH_LIC;
}
}
else if (!DdsMsgData::ScaleInfo_queue_.empty())
{ {
WeighingSystem::ScaleInfo info = std::move(DdsMsgData::ScaleInfo_queue_.front()); Queue::QueueSuccess info = std::move(DdsMsgData::QueueSuccess_queue_.front());
DdsMsgData::ScaleInfo_queue_.pop(); DdsMsgData::QueueSuccess_queue_.pop();
dds_lock.unlock(); dds_lock.unlock();
DEBUG("有车: " << info.HasVehicle()); DEBUG("==== QueueSuccess received, raising front bar ====");
DEBUG("稳定: " << info.WeightOK()); DEBUG(" message_id = " << info.message_id());
DEBUG("设备状态: " << info.State()); DEBUG(" card_number = " << info.card_number());
DEBUG("实时重量: " << info.Value()); DEBUG(" device_id = " << info.device_id());
DEBUG("稳定重量: " << info.StableValue());
if (info.WeightOK() == true) // 抬前拦车器
{
stable_weight = info.StableValue();
}
else
{
stable_weight = 0;
}
if (info.HasVehicle() == 0)
{
license_no.clear();
if (weigh_state == WEIGH_LEAVE)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::map<std::string, std::string> ctrl; std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "down"; ctrl["FrontBar"] = "up";
bar_ctrl(ctrl); bar_ctrl(ctrl);
weigh_state = WEIGH_IDLE;
}
}
}
else if (!DdsMsgData::BarUpdate_queue_.empty())
{
WeighingSystem::BarUpdate info = std::move(DdsMsgData::BarUpdate_queue_.front());
DdsMsgData::BarUpdate_queue_.pop();
dds_lock.unlock();
DEBUG("前拦车器状态: " << info.FrontBarState());
DEBUG("后拦车器状态: " << info.BackBarState());
}
else if (!DdsMsgData::LightsUpdate_queue_.empty())
{
WeighingSystem::LightsUpdate info = std::move(DdsMsgData::LightsUpdate_queue_.front());
DdsMsgData::LightsUpdate_queue_.pop();
dds_lock.unlock();
DEBUG("前红绿灯状态: " << info.FrontLEDState()); // 抬后拦车器
DEBUG("后红绿灯状态: " << info.BackLEDState()); // std::map<std::string, std::string> ctrl;
} // ctrl["BackBar"] = "up";
else if (!DdsMsgData::InfraredUpdate_queue_.empty()) // bar_ctrl(ctrl);
{
WeighingSystem::InfraredUpdate info = std::move(DdsMsgData::InfraredUpdate_queue_.front());
DdsMsgData::InfraredUpdate_queue_.pop();
dds_lock.unlock();
DEBUG("前红外对射状态: " << info.FrontResistanceSignal());
DEBUG("后红外对射状态: " << info.BackResistanceSignal());
}
else if (!DdsMsgData::WeightInfoOk_queue_.empty())
{
WeighingSystem::WeightInfoOk info = std::move(DdsMsgData::WeightInfoOk_queue_.front());
DdsMsgData::WeightInfoOk_queue_.pop();
dds_lock.unlock();
auto formatFloat = [](float value) -> std::string // 收到 QueueSuccess 后下发"排队票"打印任务(仅打一次)
{ // 字段映射QueueSuccess → Print1_3 期望的 map key
std::ostringstream oss;
oss << std::fixed << std::setprecision(0) << value;
return oss.str();
};
if (info.IsPrintTicker() == true)
{ {
std::map<std::string, std::string> print_msg; std::map<std::string, std::string> print_msg;
print_msg["Title"] = "排队票"; // 触发 print/MsgHandler2.cxx::Print1_3
print_msg["Title"] = "五彩湾"; print_msg["CarNumber"] = info.vehicle_number(); // 车牌号
print_msg["GrossDeviceID"] = std::to_string(info.GrossDeviceID()); print_msg["DateTime"] = info.queue_time(); // 时间
print_msg["GrossDeviceName"] = info.GrossDeviceName(); print_msg["QueueID"] = std::to_string(info.queue_number()); // 排队号 (long→string)
print_msg["TareDeviceID"] = std::to_string(info.TareDeviceID()); print_msg["Supplier"] = std::to_string(info.sample_code()); // 采样编码
print_msg["TareDeviceName"] = info.TareDeviceName(); print_msg["GoodsType"] = info.goods_name(); // 品种
print_msg["TitleCorp"] = info.EnterpriseName(); print_msg["sample_machine"] = info.sample_machine(); // 采样机名称
print_msg["CoalNumber"] = info.BillNumber(); print_msg["CoalYard"] = ""; // 煤场:缺省为空(冒号后无内容)
print_msg["CarNumber"] = info.CarNumber();
print_msg["Supplier"] = info.Supplier();
print_msg["GoodsType"] = info.GoodsType();
print_msg["GrossWeight"] = formatFloat(info.GrossWeight());
print_msg["GrossTime"] = info.GrossTime();
print_msg["GrossOperater"] = info.GrossOperater();
print_msg["TareWeight"] = formatFloat(info.Tare());
print_msg["TareTime"] = info.TareTime();
print_msg["TareOperater"] = info.TareOperater();
print_msg["SuttleWeight"] = formatFloat(info.Suttle());
print_msg["duduction1"] = formatFloat(info.duduction1());
print_msg["duduction2"] = formatFloat(info.duduction2());
print_msg["duduction3"] = formatFloat(info.duduction3());
print_msg["INCoalYard"] = info.INCoalYard();
print_msg["OUTCoalYard"] = info.OutCoalYard();
print_msg["BatchNumber"] = info.BatchNumber();
print_msg["Warning"] = info.Warning();
print_msg["Tips"] = info.Tips();
print_msg["TicketType"] = info.TicketType();
print_receipt(print_msg); print_receipt(print_msg);
std::this_thread::sleep_for(std::chrono::seconds(1));
} }
weigh_state = WEIGH_LEAVE;
std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "up";
bar_ctrl(ctrl);
}
else if (!DdsMsgData::WeightInfoError_queue_.empty())
{
WeighingSystem::WeightInfoError info = std::move(DdsMsgData::WeightInfoError_queue_.front());
DdsMsgData::WeightInfoError_queue_.pop();
dds_lock.unlock();
weigh_state = WEIGH_ERROR; // 记录抬杆时刻,开始 60s 倒计时
queue_success_time_ = std::chrono::steady_clock::now();
queue_success_pending_ = true;
weigh_state = WEIGH_QUEUE_RAISED;
} }
else else
{ {
@ -497,69 +396,41 @@ void PublisherApp::run()
} }
} }
// logic // 2) 状态机
switch (weigh_state) switch (weigh_state)
{ {
case WEIGH_IDLE: case WEIGH_IDLE:
break; break;
case WEIGH_LIC:
if ((stable_weight != 0) && (license_no.empty() != true)) case WEIGH_QUEUE_RAISED:
{ if (queue_success_pending_)
DEBUG("stable_weight1 " << stable_weight);
DEBUG("license_no " << license_no);
stable_weight1 = stable_weight;
weigh_state = WEIGH_STABLE1;
}
break;
case WEIGH_STABLE1:
if (stable_weight == 0)
{
DEBUG("weigh1 clear");
weigh_state = WEIGH_STABLE2;
}
break;
case WEIGH_STABLE2:
if ((stable_weight != 0) && (license_no.empty() != true))
{ {
DEBUG("license_no " << license_no); auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
DEBUG("stable_weight2 " << stable_weight); std::chrono::steady_clock::now() - queue_success_time_).count();
stable_weight2 = stable_weight; if (elapsed >= 60)
if ((stable_weight1 - stable_weight2) > 45)
{ {
weigh_state = WEIGH_SEND; DEBUG("60s elapsed after QueueSuccess, lowering front bar...");
} std::map<std::string, std::string> ctrl;
else ctrl["FrontBar"] = "down";
{ bar_ctrl(ctrl);
DEBUG("stable_weight2 error");
stable_weight1 = stable_weight; // std::map<std::string, std::string> ctrl;
weigh_state = WEIGH_STABLE1; // ctrl["BackBar"] = "down";
} // bar_ctrl(ctrl);
queue_success_pending_ = false;
weigh_state = WEIGH_IDLE;
} }
break;
case WEIGH_SEND:
DEBUG("send summary");
{
WeighingSystem::SummaryUpdate info;
info.License() = license_no;
info.StableValue() = stable_weight2;
summary_writer_->write(&info);
} }
weigh_state = WEIGH_PRINT;
break;
case WEIGH_PRINT:
break;
case WEIGH_ERROR:
std::this_thread::sleep_for(std::chrono::seconds(3));
weigh_state = WEIGH_STABLE2;
break;
case WEIGH_LEAVE:
break; break;
default: default:
weigh_state = WEIGH_IDLE; weigh_state = WEIGH_IDLE;
break; break;
} }
// Wait for period or stop event // 3) 周期等待
std::unique_lock<std::mutex> period_lock(mutex_); std::unique_lock<std::mutex> period_lock(mutex_);
cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this]() cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this]()
{ {
@ -568,7 +439,6 @@ void PublisherApp::run()
} }
} }
bool PublisherApp::publish() bool PublisherApp::publish()
{ {
bool ret = false; bool ret = false;

@ -23,6 +23,7 @@
#define FAST_DDS_GENERATED__PUBLISHERAPP_HPP #define FAST_DDS_GENERATED__PUBLISHERAPP_HPP
#include <condition_variable> #include <condition_variable>
#include <chrono>
#include <fastdds/dds/domain/DomainParticipant.hpp> #include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp> #include <fastdds/dds/domain/DomainParticipantFactory.hpp>
@ -82,6 +83,10 @@ private:
const uint32_t period_ms_ = 100; // in ms const uint32_t period_ms_ = 100; // in ms
uint16_t samples_sent_; uint16_t samples_sent_;
std::atomic<bool> stop_; std::atomic<bool> stop_;
// ── QueueSuccess 抬杆/落杆计时 ──
std::chrono::steady_clock::time_point queue_success_time_;
bool queue_success_pending_ = false;
}; };
#endif // FAST_DDS_GENERATED__PUBLISHERAPP_HPP #endif // FAST_DDS_GENERATED__PUBLISHERAPP_HPP

@ -28,17 +28,32 @@
#include <fastdds/dds/domain/DomainParticipantFactory.hpp> #include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp> #include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp> #include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <queue>
#include <mutex>
#include "msg.hpp"
// Static member definitions for DdsMsgData
// (other queue/mutex members are already defined in core/main.cxx;
// only QueueSuccess_queue_ is missing there)
std::queue<Queue::QueueSuccess> DdsMsgData::QueueSuccess_queue_;
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp> #include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp> #include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
using namespace eprosima::fastdds::dds; using namespace eprosima::fastdds::dds;
// 【新增】静态成员变量定义
// std::mutex DdsMsgData::infrared_mtx_;
// WeighingSystem::InfraredUpdate DdsMsgData::latest_infrared_;
// std::atomic<bool> DdsMsgData::stop_flag_{false};
SubscriberApp::SubscriberApp( SubscriberApp::SubscriberApp(
const int& domain_id) const int& domain_id)
: factory_(nullptr) : factory_(nullptr)
@ -68,6 +83,9 @@ SubscriberApp::SubscriberApp(
, weightinfoerror_topic_(nullptr) , weightinfoerror_topic_(nullptr)
, weightinfoerror_reader_(nullptr) , weightinfoerror_reader_(nullptr)
, weightinfoerror_type_(new WeighingSystem::WeightInfoErrorPubSubType()) , weightinfoerror_type_(new WeighingSystem::WeightInfoErrorPubSubType())
, queuesuccess_topic_(nullptr)
, queuesuccess_reader_(nullptr)
, queuesuccess_type_(new Queue::QueueSuccessPubSubType())
, samples_received_(0) , samples_received_(0)
, stop_(false) , stop_(false)
{ {
@ -92,6 +110,7 @@ SubscriberApp::SubscriberApp(
scaleinfo_type_.register_type(participant_); scaleinfo_type_.register_type(participant_);
weightinfook_type_.register_type(participant_); weightinfook_type_.register_type(participant_);
weightinfoerror_type_.register_type(participant_); weightinfoerror_type_.register_type(participant_);
queuesuccess_type_.register_type(participant_);
// Create the subscriber // Create the subscriber
SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT;
@ -317,6 +336,33 @@ SubscriberApp::SubscriberApp(
{ {
throw std::runtime_error("WeighingSystem::WeightInfoError DataReader initialization failed"); throw std::runtime_error("WeighingSystem::WeightInfoError DataReader initialization failed");
} }
// Create the topic
topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos);
queuesuccess_topic_ = participant_->create_topic("QueueSuccess", queuesuccess_type_.get_type_name(), topic_qos);
if (queuesuccess_topic_ == nullptr)
{
throw std::runtime_error("Queue::QueueSuccess Topic initialization failed");
}
// Create the reader
reader_qos = DATAREADER_QOS_DEFAULT;
subscriber_->get_default_datareader_qos(reader_qos);
reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
reader_qos.reliability().max_blocking_time = Duration_t(1, 0);
reader_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
reader_qos.history().depth = 1;
reader_qos.resource_limits().max_samples = 200;
reader_qos.resource_limits().max_instances = 1;
reader_qos.resource_limits().max_samples_per_instance = 100;
reader_qos.data_sharing().off();
queuesuccess_reader_ = subscriber_->create_datareader(queuesuccess_topic_, reader_qos, this, StatusMask::all());
if (queuesuccess_reader_ == nullptr)
{
throw std::runtime_error("Queue::QueueSuccess DataReader initialization failed");
}
} }
SubscriberApp::~SubscriberApp() SubscriberApp::~SubscriberApp()
@ -383,6 +429,7 @@ void SubscriberApp::on_data_available(
DdsMsgData::LightsUpdate_queue_.push(std::move(sample_)); DdsMsgData::LightsUpdate_queue_.push(std::move(sample_));
lock.unlock(); lock.unlock();
} }
} }
} }
} }
@ -398,6 +445,11 @@ void SubscriberApp::on_data_available(
DdsMsgData::InfraredUpdate_queue_.push(std::move(sample_)); DdsMsgData::InfraredUpdate_queue_.push(std::move(sample_));
lock.unlock(); lock.unlock();
} }
// // 【新增】保存最新红外对射状态
// {
// std::lock_guard<std::mutex> lock(DdsMsgData::infrared_mtx_);
// DdsMsgData::latest_infrared_ = sample_;
// }
} }
} }
} }
@ -476,6 +528,21 @@ void SubscriberApp::on_data_available(
} }
} }
} }
else if (topic_name == "QueueSuccess")
{
Queue::QueueSuccess sample_;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{
if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data)
{
{
std::unique_lock<std::mutex> lock(DdsMsgData::queue_cv_mtx_);
DdsMsgData::QueueSuccess_queue_.push(std::move(sample_));
lock.unlock();
}
}
}
}
} }
void SubscriberApp::run() void SubscriberApp::run()

@ -29,7 +29,7 @@
#include <fastdds/dds/subscriber/DataReaderListener.hpp> #include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp> #include <fastdds/dds/topic/TypeSupport.hpp>
#include "System.hpp" #include "WeighingDDSType.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{ {
@ -87,6 +87,10 @@ private:
eprosima::fastdds::dds::Topic* weightinfoerror_topic_; eprosima::fastdds::dds::Topic* weightinfoerror_topic_;
eprosima::fastdds::dds::DataReader* weightinfoerror_reader_; eprosima::fastdds::dds::DataReader* weightinfoerror_reader_;
eprosima::fastdds::dds::TypeSupport weightinfoerror_type_; eprosima::fastdds::dds::TypeSupport weightinfoerror_type_;
// 【新增】QueueSuccess 订阅相关
eprosima::fastdds::dds::Topic* queuesuccess_topic_;
eprosima::fastdds::dds::DataReader* queuesuccess_reader_;
eprosima::fastdds::dds::TypeSupport queuesuccess_type_;
uint16_t samples_received_; uint16_t samples_received_;
std::atomic<bool> stop_; std::atomic<bool> stop_;
uint32_t period_ms_ = 100; // in ms uint32_t period_ms_ = 100; // in ms

@ -3,10 +3,17 @@
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#include "System.hpp" #include "WeighingDDSType.hpp"
#include <atomic>
class DdsMsgData { class DdsMsgData {
public: public:
// 【修改】红外对射最新状态存储(放在最前面,保持正确缩进)
// static std::mutex infrared_mtx_;
// static WeighingSystem::InfraredUpdate latest_infrared_;
// static std::atomic<bool> stop_flag_;
static std::queue<WeighingSystem::BarUpdate> BarUpdate_queue_; static std::queue<WeighingSystem::BarUpdate> BarUpdate_queue_;
static std::queue<WeighingSystem::LightsUpdate> LightsUpdate_queue_; static std::queue<WeighingSystem::LightsUpdate> LightsUpdate_queue_;
static std::queue<WeighingSystem::InfraredUpdate> InfraredUpdate_queue_; static std::queue<WeighingSystem::InfraredUpdate> InfraredUpdate_queue_;
@ -15,7 +22,10 @@ public:
static std::queue<WeighingSystem::ScaleInfo> ScaleInfo_queue_; static std::queue<WeighingSystem::ScaleInfo> ScaleInfo_queue_;
static std::queue<WeighingSystem::WeightInfoOk> WeightInfoOk_queue_; static std::queue<WeighingSystem::WeightInfoOk> WeightInfoOk_queue_;
static std::queue<WeighingSystem::WeightInfoError> WeightInfoError_queue_; static std::queue<WeighingSystem::WeightInfoError> WeightInfoError_queue_;
static std::queue<Queue::QueueSuccess> QueueSuccess_queue_;
static std::mutex queue_cv_mtx_; static std::mutex queue_cv_mtx_;
}; };
#endif #endif

@ -33,7 +33,7 @@
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> #include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp> #include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
using namespace eprosima::fastdds::dds; using namespace eprosima::fastdds::dds;
@ -44,7 +44,7 @@ PublisherApp::PublisherApp(
, publisher_(nullptr) , publisher_(nullptr)
, topic_(nullptr) , topic_(nullptr)
, writer_(nullptr) , writer_(nullptr)
, type_(new WeighRspPubSubType()) , type_(new WeighingSystem::ScaleInfoPubSubType())
, matched_(0) , matched_(0)
, samples_sent_(0) , samples_sent_(0)
, stop_(false) , stop_(false)
@ -169,7 +169,7 @@ bool PublisherApp::publish()
if (!is_stopped()) if (!is_stopped())
{ {
/* Initialize your structure here */ /* Initialize your structure here */
WeighRsp sample_; WeighingSystem::ScaleInfo sample_;
ret = (RETCODE_OK == writer_->write(&sample_)); ret = (RETCODE_OK == writer_->write(&sample_));
} }
return ret; return ret;

@ -32,7 +32,7 @@
#include <fastdds/dds/subscriber/SampleInfo.hpp> #include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
using namespace eprosima::fastdds::dds; using namespace eprosima::fastdds::dds;
@ -43,7 +43,7 @@ SubscriberApp::SubscriberApp(
, subscriber_(nullptr) , subscriber_(nullptr)
, topic_(nullptr) , topic_(nullptr)
, reader_(nullptr) , reader_(nullptr)
, type_(new WeighReqPubSubType()) , type_(new WeighingSystem::ScaleInfoPubSubType())
, samples_received_(0) , samples_received_(0)
, stop_(false) , stop_(false)
{ {
@ -127,7 +127,7 @@ void SubscriberApp::on_subscription_matched(
void SubscriberApp::on_data_available( void SubscriberApp::on_data_available(
DataReader* reader) DataReader* reader)
{ {
WeighRsp sample_; WeighingSystem::ScaleInfo sample_;
SampleInfo info; SampleInfo info;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info))) while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{ {

@ -29,7 +29,7 @@
#include <fastdds/dds/subscriber/DataReaderListener.hpp> #include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp> #include <fastdds/dds/topic/TypeSupport.hpp>
#include "System.hpp" #include "WeighingDDSType.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{ {

Binary file not shown.

@ -212,9 +212,22 @@ void SubscriberApp::run(std::shared_ptr<MsgHandler> handler)
{ {
if(!MsgData::BarCommandUpdate_queue_.empty()) if(!MsgData::BarCommandUpdate_queue_.empty())
{ {
WeighingSystem::BarCommandUpdate cmd = std::move(MsgData::BarCommandUpdate_queue_.front()); WeighingSystem::BarCommandUpdate cmd = std::move(MsgData::BarCommandUpdate_queue_.front());
MsgData::BarCommandUpdate_queue_.pop(); MsgData::BarCommandUpdate_queue_.pop();
lock.unlock(); lock.unlock();
// std::cout << "[DEBUG] DDS Received: "
// << "FrontBarSignalUp=" << cmd.FrontBarSignalUp() << ", "
// << "FrontBarSignalDown=" << cmd.FrontBarSignalDown() << ", "
// << "FrontBarEnable=" << cmd.FrontBarEnable() << ", "
// << "BackBarSignalUp=" << cmd.BackBarSignalUp() << ", "
// << "BackBarSignalDown=" << cmd.BackBarSignalDown() << ", "
// << "BackBarEnable=" << cmd.BackBarEnable()
// << std::endl;
std::vector<std::string> port; std::vector<std::string> port;
if (!std::filesystem::exists(getExeDir() / "frontbar.lock")) if (!std::filesystem::exists(getExeDir() / "frontbar.lock"))
{ {

@ -34,6 +34,43 @@
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
// ── 拦车器测试函数 ──
void bar_test(std::shared_ptr<MsgHandler> handler, const std::string& bar_name)
{
DEBUG(bar_name + " test started...");
std::this_thread::sleep_for(std::chrono::seconds(3));
DEBUG("3 seconds elapsed, raising " + bar_name + "...");
std::vector<std::string> ports;
ports.push_back(bar_name + "BarUp");
handler->CtrlBar(ports);
// 等待 CtrlBar 内部所有消息发送完成
std::this_thread::sleep_for(std::chrono::seconds(5));
DEBUG("5 seconds elapsed, lowering " + bar_name + "...");
ports.clear();
ports.push_back(bar_name + "BarDown");
handler->CtrlBar(ports);
DEBUG(bar_name + " test completed.");
}
void front_bar_test(std::shared_ptr<MsgHandler> handler)
{
bar_test(handler, "Front");
}
void back_bar_test(std::shared_ptr<MsgHandler> handler)
{
bar_test(handler, "Back");
}
using eprosima::fastdds::dds::Log; using eprosima::fastdds::dds::Log;
std::function<void(int)> stop_handler; std::function<void(int)> stop_handler;
@ -87,6 +124,14 @@ int main(int argc, char** argv)
{ {
domain_id = atoi(argv[++i]); domain_id = atoi(argv[++i]);
} }
else if (strcmp(argv[i], "--test_front_bar") == 0)
{
// 启用前拦车器测试功能
}
else if (strcmp(argv[i], "--test_back_bar") == 0)
{
// 启用后拦车器测试功能
}
else if (strcmp(argv[i], "--interface") == 0 && i + 1 < argc) else if (strcmp(argv[i], "--interface") == 0 && i + 1 < argc)
{ {
interface = argv[++i]; interface = argv[++i];
@ -122,7 +167,8 @@ int main(int argc, char** argv)
<< " --port Set port name (e.g., can0)\n" << " --port Set port name (e.g., can0)\n"
<< " --device Set device name (e.g., 5serial)\n" << " --device Set device name (e.g., 5serial)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n"
<< " --test_front_bar Test front bar (raise after 3s, lower after 3s)\n";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
else else
@ -136,7 +182,8 @@ int main(int argc, char** argv)
<< " --port Set port name (e.g., can0)\n" << " --port Set port name (e.g., can0)\n"
<< " --device Set device name (e.g., 5serial)\n" << " --device Set device name (e.g., 5serial)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n"
<< " --test_front_bar Test front bar (raise after 3s, lower after 3s)\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -149,6 +196,33 @@ int main(int argc, char** argv)
dev->device = device; dev->device = device;
dev->device_id = device_id; dev->device_id = device_id;
// ── 拦车器测试模式 ──
bool test_front_bar = false;
bool test_back_bar = false;
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--test_front_bar") == 0)
{
test_front_bar = true;
}
else if (strcmp(argv[i], "--test_back_bar") == 0)
{
test_back_bar = true;
}
}
std::thread test_thread;
if (test_front_bar)
{
test_thread = std::thread(front_bar_test, dev);
}
else if (test_back_bar)
{
test_thread = std::thread(back_bar_test, dev);
}
std::thread sub_thread(&SubscriberApp::run, sub, dev); std::thread sub_thread(&SubscriberApp::run, sub, dev);
std::thread pub_thread(&PublisherApp::run, pub, dev); std::thread pub_thread(&PublisherApp::run, pub, dev);
@ -169,6 +243,11 @@ int main(int argc, char** argv)
signal(SIGHUP, signal_handler); signal(SIGHUP, signal_handler);
#endif // _WIN32 #endif // _WIN32
if (test_front_bar || test_back_bar)
{
test_thread.join();
}
sub_thread.join(); sub_thread.join();
pub_thread.join(); pub_thread.join();

@ -26,6 +26,7 @@
#include <stdexcept> #include <stdexcept>
#include <thread> #include <thread>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp> #include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/log/Log.hpp> #include <fastdds/dds/log/Log.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp> #include <fastdds/dds/publisher/DataWriter.hpp>
@ -154,6 +155,10 @@ void PublisherApp::run(std::shared_ptr<HTTPServer> handler)
if (handler->PostMsg.empty() != true) if (handler->PostMsg.empty() != true)
{ {
std::cout << "[HTTPServer] 原始数据: " << handler->PostMsg << std::endl;
json j = json::parse(handler->PostMsg); json j = json::parse(handler->PostMsg);
DEBUG("车牌: " << j["AlarmInfoPlate"]["result"]["PlateResult"]["license"]); DEBUG("车牌: " << j["AlarmInfoPlate"]["result"]["PlateResult"]["license"]);

@ -4,179 +4,64 @@
#include <thread> #include <thread>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> // for O_WRONLY
#include <chrono>
#include "MsgHandler.hpp" #include "MsgHandler.hpp"
MsgHandler::MsgHandler() : fd(-1) {} MsgHandler::MsgHandler() : fd(-1) {}
void MsgHandler::HandleDdsMsg(const std::map<std::string, std::string>& msg)
{
auto cmd = msg.find("cmd");
if (cmd != msg.end()) static int gpio_export(int n)
{
if (cmd->second == "config")
{
auto port = msg.find("port");
auto baudrate = msg.find("baudrate");
auto device = msg.find("device");
if ((port != msg.end()) && (baudrate != msg.end()) && (device != msg.end()))
{
OpenPort(port->second, baudrate->second);
this->device = device->second;
}
}
else if (cmd->second == "open")
{
if (this->device == "5serial")
{
std::vector<uint8_t> data;
data.insert(data.end(), {this->device_id, 0x50, 1, 1});
SendDeviceMsg(data);
}
}
else if (cmd->second == "write")
{
if (this->device == "5serial")
{
std::vector<uint8_t> data;
data.resize(8, 1);
data.insert(data.begin(), {this->device_id, 0x51, 1});
for (const auto &port : this->iomap.omap)
{ {
data[port.second.first+2] = port.second.second; int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) return -1;
char buf[16]; int len = snprintf(buf, sizeof(buf), "%d", n);
write(fd, buf, len);
close(fd);
usleep(100000);
return 0;
} }
for (auto &m : msg) static int gpio_set_dir(int n, const char* dir)
{
auto port = this->iomap.omap.find(m.first);
if (port != this->iomap.omap.end())
{
if (m.second == "1")
{
port->second.second = 1;
}
else if (m.second == "0")
{
port->second.second = 0;
}
data[port->second.first+2] = port->second.second;
}
}
SendDeviceMsg(data);
}
}
else if (cmd->second == "pluse")
{ {
if (this->device == "5serial") char path[64]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", n);
{ int fd = open(path, O_WRONLY);
std::vector<uint8_t> data; if (fd < 0) return -1;
data.resize(8, 1); write(fd, dir, strlen(dir));
data.insert(data.begin(), {this->device_id, 0x51, 1}); close(fd);
for (const auto &port : this->iomap.omap) return 0;
{
data[port.second.first+2] = port.second.second;
} }
for (auto &m : msg) static int gpio_write(int n, int val)
{
auto port = this->iomap.omap.find(m.first);
if (port != this->iomap.omap.end())
{
if (m.second == "1")
{ {
port->second.second = 1; char path[64]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);
} int fd = open(path, O_WRONLY);
else if (m.second == "0") if (fd < 0) return -1;
{ char b = val ? '1' : '0';
port->second.second = 0; write(fd, &b, 1);
} close(fd);
data[port->second.first+2] = port->second.second; return 0;
}
} }
SendDeviceMsg(data);
std::this_thread::sleep_for(std::chrono::seconds(1));
for (auto &m : msg) bool MsgHandler::OpenPort(const std::string& port, const std::string& baudrate)
{
auto port = this->iomap.omap.find(m.first);
if (port != this->iomap.omap.end())
{
if (m.second == "1")
{
port->second.second = 0;
}
else if (m.second == "0")
{
port->second.second = 1;
}
data[port->second.first+2] = port->second.second;
}
}
SendDeviceMsg(data);
}
}
else if (cmd->second == "read")
{
if (this->device == "5serial")
{ {
std::vector<uint8_t> data; std::cout << "[debug] OpenPort device=" << this->device
data.insert(data.end(), {this->device_id, 0x52, 1}); << " omap.size=" << this->iomap.omap.size() << std::endl;
data.insert(data.end(), 1);
SendDeviceMsg(data);
}
}
}
}
int MsgHandler::ParseDeviceMsg(std::vector<uint8_t>& data, InternalSystem::IoCtrlRsp& rsp) if (this->device == "gpio")
{
if (data[0] == this->device_id)
{ {
switch(data[1]) // ★ 前拦车器两个 GPIO先显式 export + direction + 写 0不依赖 map 顺序)
{ gpio_export(48);
case 0x50: gpio_set_dir(48, "out");
rsp.msg()["open"] = std::to_string(data[3]); gpio_write(48, 0);
break;
case 0x51:
rsp.msg()["write"] = std::to_string(data[3]);
break;
case 0x52:
rsp.msg()["read"] = "0";
for (auto &p : this->iomap.imap)
{
// if (p.second.second != data[p.second.first+2])
// {
p.second.second = data[p.second.first+2];
rsp.msg()[p.first] = std::to_string(p.second.second);
// }
}
break;
}
return 1;
}
return 0;
}
int MsgHandler::HandleDeviceMsg(InternalSystem::IoCtrlRsp& rsp) gpio_export(49);
{ gpio_set_dir(49, "out");
std::vector<uint8_t> m_RecvData; gpio_write(49, 0);
if(RecvDeviceMsg(m_RecvData, 100) > 0) return true;
{
for (int num : m_RecvData)
{
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< num << " ";
}
std::cout << std::endl;
return(ParseDeviceMsg(m_RecvData, rsp));
}
return 0;
} }
bool MsgHandler::OpenPort(const std::string& port, const std::string& baudrate)
{
return true; return true;
} }
@ -270,3 +155,62 @@ int MsgHandler::RecvDeviceMsg(std::vector<uint8_t>& data, int timeoutMs)
return RecvMsg(data.data(), data.size(), timeoutMs); return RecvMsg(data.data(), data.size(), timeoutMs);
} }
void MsgHandler::HandleBarCommand(const WeighingSystem::BarCommandUpdate& cmd)
{
if (this->device != "gpio") return;
// 前拦车器升杆
if (cmd.FrontBarEnable() && cmd.FrontBarSignalUp())
{
auto up = this->iomap.omap.find("frontbarrup");
if (up != this->iomap.omap.end())
{
// ① 抬杆前:先 init 48 + 49 全部拉低
std::cout << "[GPIO] >>> init 48+49 before raise" << std::endl;
this->InitFrontBarGpioPair();
// ② 抬杆48 置 1
int n = up->second.first;
std::cout << "[GPIO] " << n << " <- 1 (raise start)" << std::endl;
int rc = gpio_write(n, 1);
std::cout << "[GPIO] " << n << " <- 1 rc=" << rc << std::endl;
up->second.second = 1;
// ③ 保持 10 秒
std::cout << "[GPIO] hold raise 10s..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
// ④ 抬杆后:再 init 一次,强制两脚回 0
std::cout << "[GPIO] >>> init 48+49 after 10s (reset to 0)" << std::endl;
this->InitFrontBarGpioPair();
up->second.second = 0;
std::cout << "[GPIO] reset done" << std::endl;
}
}
}
void MsgHandler::InitFrontBarGpioPair()
{
// 强制重新 init frontbarrup (48) 和 frontbardown (49)
auto up = iomap.omap.find("frontbarrup");
auto dn = iomap.omap.find("frontbardown");
if (up != iomap.omap.end())
{
int n = up->second.first; // 48
gpio_export(n);
gpio_set_dir(n, "out");
gpio_write(n, 0);
std::cout << "[GPIO] " << n << " init <- 0" << std::endl;
}
if (dn != iomap.omap.end())
{
int n = dn->second.first; // 49
gpio_export(n);
gpio_set_dir(n, "out");
gpio_write(n, 0);
std::cout << "[GPIO] " << n << " init <- 0" << std::endl;
}
}

@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include "System.hpp" #include "WeighingDDSType.hpp"
struct iomap_t struct iomap_t
{ //name, (port, value) { //name, (port, value)
@ -25,9 +25,6 @@ public:
MsgHandler(); MsgHandler();
~MsgHandler() = default; ~MsgHandler() = default;
void HandleDdsMsg(const std::map<std::string, std::string>& msg);
int HandleDeviceMsg(InternalSystem::IoCtrlRsp& rsp);
virtual bool OpenPort(const std::string& port, const std::string& baudrate); virtual bool OpenPort(const std::string& port, const std::string& baudrate);
virtual int SendDeviceMsg(std::vector<uint8_t>& data); virtual int SendDeviceMsg(std::vector<uint8_t>& data);
virtual int RecvDeviceMsg(std::vector<uint8_t>& data, int timeoutMs); virtual int RecvDeviceMsg(std::vector<uint8_t>& data, int timeoutMs);
@ -38,8 +35,14 @@ public:
} }
void ClosePort(); void ClosePort();
void HandleBarCommand(const WeighingSystem::BarCommandUpdate& cmd);
// 前拦车器两个 GPIO 显式 initexport + direction + 写 0
// 失败也不抛异常,保证调用点可以无脑连续调
void InitFrontBarGpioPair();
private: private:
int ParseDeviceMsg(std::vector<uint8_t>& data, InternalSystem::IoCtrlRsp& rsp);
}; };
#endif #endif

@ -1,197 +0,0 @@
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*!
* @file Publisher.cxx
* This file contains the implementation of the publisher functions.
*
* This file was generated by the tool fastddsgen.
*/
#include "Publisher.hpp"
#include <condition_variable>
#include <csignal>
#include <stdexcept>
#include <thread>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/log/Log.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include "SystemPubSubTypes.hpp"
#include "msg.hpp"
#include "MsgHandler.hpp"
using namespace eprosima::fastdds::dds;
PublisherApp::PublisherApp(
const int& domain_id)
: factory_(nullptr)
, participant_(nullptr)
, publisher_(nullptr)
, topic_(nullptr)
, writer_(nullptr)
, type_(new InternalSystem::IoCtrlRspPubSubType())
, matched_(0)
, samples_sent_(0)
, stop_(false)
{
//
// Create the participant
DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("IoCtrl_pub_participant");
pqos.wire_protocol().builtin.discovery_config.leaseDuration = Duration_t(60, 0);
pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = Duration_t(30, 0);
factory_ = DomainParticipantFactory::get_shared_instance();
participant_ = factory_->create_participant(domain_id, pqos, nullptr, StatusMask::none());
if (participant_ == nullptr)
{
throw std::runtime_error("InternalSystem::IoCtrlRsp Participant initialization failed");
}
// Register the type
type_.register_type(participant_);
// Create the publisher
PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT;
participant_->get_default_publisher_qos(pub_qos);
publisher_ = participant_->create_publisher(pub_qos, nullptr, StatusMask::none());
if (publisher_ == nullptr)
{
throw std::runtime_error("InternalSystem::IoCtrlRsp Publisher initialization failed");
}
// Create the topic
TopicQos topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos);
topic_ = participant_->create_topic("InternalSystem::IoCtrlRspTopic", type_.get_type_name(), topic_qos);
if (topic_ == nullptr)
{
throw std::runtime_error("InternalSystem::IoCtrlRsp Topic initialization failed");
}
// Create the data writer
DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT;
publisher_->get_default_datawriter_qos(writer_qos);
writer_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
writer_qos.durability().kind = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS;
writer_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
writer_ = publisher_->create_datawriter(topic_, writer_qos, this, StatusMask::all());
if (writer_ == nullptr)
{
throw std::runtime_error("InternalSystem::IoCtrlRsp DataWriter initialization failed");
}
}
PublisherApp::~PublisherApp()
{
if (nullptr != participant_)
{
// Delete DDS entities contained within the DomainParticipant
participant_->delete_contained_entities();
// Delete DomainParticipant
factory_->delete_participant(participant_);
}
}
void PublisherApp::on_publication_matched(
DataWriter* writer,
const PublicationMatchedStatus& info)
{
if (info.current_count_change == 1)
{
{
std::lock_guard<std::mutex> lock(mutex_);
matched_ = info.current_count;
}
std::cout << writer->get_topic()->get_name() << " Publisher matched." << std::endl;
cv_.notify_one();
}
else if (info.current_count_change == -1)
{
{
std::lock_guard<std::mutex> lock(mutex_);
matched_ = info.current_count;
}
std::cout << writer->get_topic()->get_name() << " Publisher unmatched." << std::endl;
}
else
{
std::cout << info.current_count_change
<< " is not a valid value for PublicationMatchedStatus current count change" << std::endl;
}
}
void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
{
InternalSystem::IoCtrlRsp rsp;
while (!is_stopped())
{
if(handler->isOpen() == true)
{
if(handler->HandleDeviceMsg(rsp))
{
writer_->write(&rsp);
rsp.msg().clear();
}
}
// Wait for period or stop event
std::unique_lock<std::mutex> period_lock(mutex_);
cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this]()
{
return is_stopped();
});
}
}
bool PublisherApp::publish()
{
bool ret = false;
// Wait for the data endpoints discovery
std::unique_lock<std::mutex> matched_lock(mutex_);
cv_.wait(matched_lock, [&]()
{
// at least one has been discovered
return ((matched_ > 0) || is_stopped());
});
if (!is_stopped())
{
/* Initialize your structure here */
InternalSystem::IoCtrlRsp sample_;
ret = (RETCODE_OK == writer_->write(&sample_));
}
return ret;
}
bool PublisherApp::is_stopped()
{
return stop_.load();
}
void PublisherApp::stop()
{
stop_.store(true);
cv_.notify_one();
}

@ -1,76 +0,0 @@
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*!
* @file PublisherApp.hpp
* This header file contains the declaration of the publisher functions.
*
* This file was generated by the tool fastddsgen.
*/
#ifndef FAST_DDS_GENERATED__PUBLISHERAPP_HPP
#define FAST_DDS_GENERATED__PUBLISHERAPP_HPP
#include <condition_variable>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriterListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "MsgHandler.hpp"
class PublisherApp : public eprosima::fastdds::dds::DataWriterListener
{
public:
PublisherApp(
const int& domain_id);
~PublisherApp();
//! Publisher matched method
void on_publication_matched(
eprosima::fastdds::dds::DataWriter* writer,
const eprosima::fastdds::dds::PublicationMatchedStatus& info) override;
//! Run publisher
void run(std::shared_ptr<MsgHandler> handler);
//! Trigger the end of execution
void stop();
private:
//! Return the current state of execution
bool is_stopped();
//! Publish a sample
bool publish();
std::shared_ptr<eprosima::fastdds::dds::DomainParticipantFactory> factory_;
eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Publisher* publisher_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataWriter* writer_;
eprosima::fastdds::dds::TypeSupport type_;
std::condition_variable cv_;
int32_t matched_;
std::mutex mutex_;
const uint32_t period_ms_ = 100; // in ms
uint16_t samples_sent_;
std::atomic<bool> stop_;
};
#endif // FAST_DDS_GENERATED__PUBLISHERAPP_HPP

@ -32,7 +32,7 @@
#include <fastdds/dds/subscriber/SampleInfo.hpp> #include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
@ -43,9 +43,9 @@ SubscriberApp::SubscriberApp(
: factory_(nullptr) : factory_(nullptr)
, participant_(nullptr) , participant_(nullptr)
, subscriber_(nullptr) , subscriber_(nullptr)
, topic_(nullptr) , bar_topic_(nullptr)
, reader_(nullptr) , bar_reader_(nullptr)
, type_(new InternalSystem::IoCtrlReqPubSubType()) , bar_type_(new WeighingSystem::BarCommandUpdatePubSubType())
, samples_received_(0) , samples_received_(0)
, stop_(false) , stop_(false)
{ {
@ -61,37 +61,38 @@ SubscriberApp::SubscriberApp(
throw std::runtime_error("InternalSystem::IoCtrlReq Participant initialization failed"); throw std::runtime_error("InternalSystem::IoCtrlReq Participant initialization failed");
} }
// Register the type
type_.register_type(participant_);
// Create the subscriber // Create the subscriber
SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT;
participant_->get_default_subscriber_qos(sub_qos); participant_->get_default_subscriber_qos(sub_qos);
subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none()); subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none());
if (subscriber_ == nullptr) if (subscriber_ == nullptr)
{ {
throw std::runtime_error("InternalSystem::IoCtrlReq Subscriber initialization failed"); throw std::runtime_error("IoCtrl Subscriber initialization failed");
} }
// Create the topic // Register the type
TopicQos topic_qos = TOPIC_QOS_DEFAULT; bar_type_.register_type(participant_);
participant_->get_default_topic_qos(topic_qos);
topic_ = participant_->create_topic("InternalSystem::IoCtrlReqTopic", type_.get_type_name(), topic_qos); // 创建 BarCommandUpdate Topic
if (topic_ == nullptr) TopicQos bar_topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(bar_topic_qos);
bar_topic_ = participant_->create_topic("BarCommandUpdate", bar_type_.get_type_name(), bar_topic_qos);
if (bar_topic_ == nullptr)
{ {
throw std::runtime_error("InternalSystem::IoCtrlReq Topic initialization failed"); throw std::runtime_error("BarCommandUpdate Topic initialization failed");
} }
// Create the reader // 创建 BarCommandUpdate Reader
DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT; DataReaderQos bar_reader_qos = DATAREADER_QOS_DEFAULT;
subscriber_->get_default_datareader_qos(reader_qos); subscriber_->get_default_datareader_qos(bar_reader_qos); // ← 现在 subscriber_ 已创建
reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; bar_reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
reader_qos.durability().kind = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS; bar_reader_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; bar_reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
reader_ = subscriber_->create_datareader(topic_, reader_qos, this, StatusMask::all()); bar_reader_qos.history().depth = 1;
if (reader_ == nullptr) bar_reader_ = subscriber_->create_datareader(bar_topic_, bar_reader_qos, this, StatusMask::all());
if (bar_reader_ == nullptr)
{ {
throw std::runtime_error("InternalSystem::IoCtrlReq DataReader initialization failed"); throw std::runtime_error("BarCommandUpdate DataReader initialization failed");
} }
} }
@ -133,22 +134,20 @@ void SubscriberApp::on_data_available(
std::string topic_name = reader->get_topicdescription()->get_name(); std::string topic_name = reader->get_topicdescription()->get_name();
std::cout << topic_name << std::endl; std::cout << topic_name << std::endl;
if (topic_name == "InternalSystem::IoCtrlReqTopic") if (topic_name == "BarCommandUpdate")
{ {
InternalSystem::IoCtrlReq sample_; WeighingSystem::BarCommandUpdate sample_;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info))) while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{ {
if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data)
{
{ {
std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_); std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_);
MsgData::IoCtrlReq_queue_.push(std::move(sample_)); MsgData::BarCommandUpdate_queue_.push(std::move(sample_));
lock.unlock(); lock.unlock();
} }
} }
} }
} }
}
void SubscriberApp::run(std::shared_ptr<MsgHandler> handler) void SubscriberApp::run(std::shared_ptr<MsgHandler> handler)
{ {
@ -157,12 +156,13 @@ void SubscriberApp::run(std::shared_ptr<MsgHandler> handler)
std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_, std::try_to_lock); std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_, std::try_to_lock);
if (lock.owns_lock()) if (lock.owns_lock())
{ {
if(!MsgData::IoCtrlReq_queue_.empty()) //BarCommandUpdate 分支
if(!MsgData::BarCommandUpdate_queue_.empty())
{ {
InternalSystem::IoCtrlReq req = std::move(MsgData::IoCtrlReq_queue_.front()); WeighingSystem::BarCommandUpdate cmd = std::move(MsgData::BarCommandUpdate_queue_.front());
MsgData::IoCtrlReq_queue_.pop(); MsgData::BarCommandUpdate_queue_.pop();
lock.unlock(); lock.unlock();
handler->HandleDdsMsg(req.msg()); handler->HandleBarCommand(cmd);
} }
else else
{ {

@ -29,8 +29,9 @@
#include <fastdds/dds/subscriber/DataReaderListener.hpp> #include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp> #include <fastdds/dds/topic/TypeSupport.hpp>
#include "System.hpp"
#include "MsgHandler.hpp" #include "MsgHandler.hpp"
#include "WeighingDDSType.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{ {
@ -64,9 +65,11 @@ private:
std::shared_ptr<eprosima::fastdds::dds::DomainParticipantFactory> factory_; std::shared_ptr<eprosima::fastdds::dds::DomainParticipantFactory> factory_;
eprosima::fastdds::dds::DomainParticipant* participant_; eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Subscriber* subscriber_; eprosima::fastdds::dds::Subscriber* subscriber_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataReader* reader_; eprosima::fastdds::dds::Topic* bar_topic_;
eprosima::fastdds::dds::TypeSupport type_; eprosima::fastdds::dds::DataReader* bar_reader_;
eprosima::fastdds::dds::TypeSupport bar_type_;
uint16_t samples_received_; uint16_t samples_received_;
std::atomic<bool> stop_; std::atomic<bool> stop_;
uint32_t period_ms_ = 100; // in ms uint32_t period_ms_ = 100; // in ms

@ -28,15 +28,19 @@
#include <fstream> #include <fstream>
#include <filesystem> #include <filesystem>
#include <limits.h> #include <limits.h>
#include <unistd.h> // ← 加这行open / close / write / read / usleep
#include <fcntl.h> // ← 加这行O_WRONLY
#include <fastdds/dds/log/Log.hpp> #include <fastdds/dds/log/Log.hpp>
#include "Subscriber.hpp" #include "Subscriber.hpp"
#include "Publisher.hpp"
#include "CanMsgHandler.hpp" #include "CanMsgHandler.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "json.hpp" #include "json.hpp"
#include <chrono>
#include "WeighingDDSType.hpp"
using eprosima::fastdds::dds::Log; using eprosima::fastdds::dds::Log;
using json = nlohmann::json; using json = nlohmann::json;
@ -67,7 +71,7 @@ std::string parse_signal(
} }
} }
std::queue<InternalSystem::IoCtrlReq> MsgData::IoCtrlReq_queue_; std::queue<WeighingSystem::BarCommandUpdate> MsgData::BarCommandUpdate_queue_;
std::mutex MsgData::queue_cv_mtx_; std::mutex MsgData::queue_cv_mtx_;
std::filesystem::path getExeDir() std::filesystem::path getExeDir()
@ -82,7 +86,6 @@ int main(int argc, char** argv)
auto ret = EXIT_SUCCESS; auto ret = EXIT_SUCCESS;
json config; json config;
std::shared_ptr<SubscriberApp> sub; std::shared_ptr<SubscriberApp> sub;
std::shared_ptr<PublisherApp> pub;
std::shared_ptr<MsgHandler> dev; std::shared_ptr<MsgHandler> dev;
int domain_id = 0; int domain_id = 0;
@ -92,6 +95,9 @@ int main(int argc, char** argv)
const char* device = "5serial"; const char* device = "5serial";
int device_id = 0; int device_id = 0;
bool test_front_bar = false;
std::thread test_thread;
auto exeDir = getExeDir(); auto exeDir = getExeDir();
auto configPath = exeDir / "config.json"; auto configPath = exeDir / "config.json";
std::ifstream file(configPath); std::ifstream file(configPath);
@ -105,6 +111,10 @@ int main(int argc, char** argv)
{ {
domain_id = atoi(argv[++i]); domain_id = atoi(argv[++i]);
} }
else if (strcmp(argv[i], "--test_front_bar") == 0)
{
test_front_bar = true;
}
else if (strcmp(argv[i], "--interface") == 0 && i + 1 < argc) else if (strcmp(argv[i], "--interface") == 0 && i + 1 < argc)
{ {
interface = argv[++i]; interface = argv[++i];
@ -140,7 +150,8 @@ int main(int argc, char** argv)
<< " --port Set port name (e.g., can0)\n" << " --port Set port name (e.g., can0)\n"
<< " --device Set device name (e.g., 5serial)\n" << " --device Set device name (e.g., 5serial)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n"
<< " --test_front_bar Test: raise front bar after 3s, lower after 5s\n";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
else else
@ -154,22 +165,76 @@ int main(int argc, char** argv)
<< " --port Set port name (e.g., can0)\n" << " --port Set port name (e.g., can0)\n"
<< " --device Set device name (e.g., 5serial)\n" << " --device Set device name (e.g., 5serial)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n"
<< " --test_front_bar Test: raise front bar after 3s, lower after 5s\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
sub = std::make_shared<SubscriberApp>(domain_id); sub = std::make_shared<SubscriberApp>(domain_id);
pub = std::make_shared<PublisherApp>(domain_id);
dev = std::make_shared<CanMsgHandler>(); dev = std::make_shared<CanMsgHandler>();
dev->OpenPort(port, baudrate); // ★ 先设 device / device_id / iomap
dev->device = device; dev->device = device;
dev->device_id = device_id; dev->device_id = device_id;
dev->iomap.imap = config["ioctrl"]["iomap"]["in"].get<std::map<std::string, std::pair<uint8_t, uint8_t>>>(); dev->iomap.imap = config["ioctrl"]["iomap"]["in"]
dev->iomap.omap = config["ioctrl"]["iomap"]["out"].get<std::map<std::string, std::pair<uint8_t, uint8_t>>>(); .get<std::map<std::string, std::pair<uint8_t, uint8_t>>>();
dev->iomap.omap = config["ioctrl"]["iomap"]["out"]
.get<std::map<std::string, std::pair<uint8_t, uint8_t>>>();
// ★ 最后才 OpenPort这时 this->device == "gpio" 才生效)
dev->OpenPort(port, baudrate);
// ★ 当 device == "gpio" 时,强制 init 48/49因为 CanMsgHandler::OpenPort 不会做)
if (dev->device == "gpio")
{
auto write_gpio = [](int n, int v) {
char path[64];
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);
int fd = open(path, O_WRONLY);
if (fd >= 0) { write(fd, v ? "1" : "0", 1); close(fd); }
};
auto export_gpio = [](int n) {
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd >= 0) { char b[8]; int l = snprintf(b, sizeof(b), "%d", n);
write(fd, b, l); close(fd); usleep(100000); }
};
auto dir_gpio = [](int n, const char* d) {
char path[64];
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", n);
int fd = open(path, O_WRONLY);
if (fd >= 0) { write(fd, d, strlen(d)); close(fd); }
};
export_gpio(48); dir_gpio(48, "out"); write_gpio(48, 0);
export_gpio(49); dir_gpio(49, "out"); write_gpio(49, 0);
}
if (test_front_bar)
{
test_thread = std::thread([dev]()
{
std::cout << "[test] sleep 3s, then raise front bar..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
WeighingSystem::BarCommandUpdate cmd_up;
cmd_up.FrontBarEnable() = 1;
cmd_up.FrontBarSignalUp() = 1;
cmd_up.FrontBarSignalDown()= 0;
cmd_up.BackBarEnable() = 0;
dev->HandleBarCommand(cmd_up);
std::cout << "[test] raise front bar done." << std::endl;
// 5 秒后降杆的代码整段删掉
});
}
std::thread sub_thread(&SubscriberApp::run, sub, dev);
std::thread pub_thread(&PublisherApp::run, pub, dev);
std::cout << "Program is running. Please press Ctrl+C to stop at any time." << std::endl; std::cout << "Program is running. Please press Ctrl+C to stop at any time." << std::endl;
@ -177,7 +242,8 @@ int main(int argc, char** argv)
{ {
std::cout << "\n" << parse_signal(signum) << " received, stopping " << argv[1] std::cout << "\n" << parse_signal(signum) << " received, stopping " << argv[1]
<< " execution." << std::endl; << " execution." << std::endl;
pub->stop();
sub->stop(); // ← 新增
}; };
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
@ -187,7 +253,12 @@ int main(int argc, char** argv)
signal(SIGHUP, signal_handler); signal(SIGHUP, signal_handler);
#endif // _WIN32 #endif // _WIN32
pub_thread.join(); sub_thread.join();
if (test_front_bar && test_thread.joinable())
{
test_thread.detach(); // 测试线程自己跑完,主线程不等
}
Log::Reset(); Log::Reset();
return ret; return ret;

@ -3,11 +3,11 @@
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#include "System.hpp" #include "WeighingDDSType.hpp"
class MsgData { class MsgData {
public: public:
static std::queue<InternalSystem::IoCtrlReq> IoCtrlReq_queue_; static std::queue<WeighingSystem::BarCommandUpdate> BarCommandUpdate_queue_; // 新增
static std::mutex queue_cv_mtx_; static std::mutex queue_cv_mtx_;
}; };

@ -0,0 +1,209 @@
// led/BX6K1YYProtocol.cxx
#include "BX6K1YYProtocol.hpp"
#include <algorithm>
namespace led {
namespace {
inline void appendLe16(std::vector<uint8_t>& v, uint16_t value) {
v.push_back(static_cast<uint8_t>(value & 0xff));
v.push_back(static_cast<uint8_t>((value >> 8) & 0xff));
}
inline void appendLe32(std::vector<uint8_t>& v, uint32_t value) {
v.push_back(static_cast<uint8_t>(value & 0xff));
v.push_back(static_cast<uint8_t>((value >> 8) & 0xff));
v.push_back(static_cast<uint8_t>((value >> 16) & 0xff));
v.push_back(static_cast<uint8_t>((value >> 24) & 0xff));
}
std::vector<uint8_t> escape(const std::vector<uint8_t>& in) {
std::vector<uint8_t> out;
out.reserve(in.size());
for (uint8_t b : in) {
switch (b) {
case 0xA5: out.push_back(0xA6); out.push_back(0x02); break;
case 0xA6: out.push_back(0xA6); out.push_back(0x01); break;
case 0x5A: out.push_back(0x5B); out.push_back(0x02); break;
case 0x5B: out.push_back(0x5B); out.push_back(0x01); break;
default: out.push_back(b); break;
}
}
return out;
}
} // anonymous namespace
uint16_t crc16(const std::vector<uint8_t>& data) {
uint16_t crc = 0;
for (uint8_t b : data) {
crc ^= b;
for (int i = 0; i < 8; ++i) {
crc = (crc & 1u) ? static_cast<uint16_t>((crc >> 1) ^ 0xA001u)
: static_cast<uint16_t>(crc >> 1);
}
}
return crc;
}
std::vector<uint8_t> makeFrame(const std::vector<uint8_t>& payload) {
std::vector<uint8_t> phy1;
appendLe16(phy1, 0xFFFE); // 目标:广播/任意控制器
appendLe16(phy1, 0x8000); // 源PC
phy1.push_back(0x00); // barcode 选项:关
phy1.push_back(0x00);
phy1.push_back(0x00);
phy1.push_back(0x00); // CRC16 模式
phy1.push_back(0x00); // 显示模式(动态区域文本)
phy1.push_back(kDeviceType);
phy1.push_back(kProtocolVersion);
appendLe16(phy1, static_cast<uint16_t>(payload.size()));
phy1.insert(phy1.end(), payload.begin(), payload.end());
uint16_t cs = crc16(phy1);
phy1.push_back(static_cast<uint8_t>(cs & 0xff));
phy1.push_back(static_cast<uint8_t>((cs >> 8) & 0xff));
std::vector<uint8_t> frame;
frame.reserve(9 + phy1.size() * 2);
frame.insert(frame.end(), 8, 0xA5); // 8 字节头
auto esc = escape(phy1);
frame.insert(frame.end(), esc.begin(), esc.end());
frame.push_back(0x5A); // 1 字节尾
return frame;
}
std::vector<uint8_t> buildScreenParameterQueryFrame() {
return makeFrame(std::vector<uint8_t>{0xA2, 0x0A, 0x01, 0x00, 0x00});
}
// 27 字节 AreaHeader + 文本内容(与 Windows 版 buildArea 等价)
static std::vector<uint8_t> buildArea(const std::string& text,
int screenWidth,
int areaY, int areaHeight,
int areaId,
bool expireWhenNotUpdated,
int timeoutSeconds) {
std::vector<uint8_t> area;
area.reserve(27 + text.size());
area.push_back(0x00); // AreaType: 字符
appendLe16(area, 0x8000); // AreaX: 0像素单位
appendLe16(area, static_cast<uint16_t>(areaY));
appendLe16(area, static_cast<uint16_t>(0x8000 | screenWidth));
appendLe16(area, static_cast<uint16_t>(areaHeight));
area.push_back(static_cast<uint8_t>(areaId));
area.push_back(0x00); // 行间距
area.push_back(expireWhenNotUpdated ? 0x02 : 0x00); // RunMode
int t = (timeoutSeconds < 0) ? 0 : (timeoutSeconds > 0xffff ? 0xffff : timeoutSeconds);
appendLe16(area, static_cast<uint16_t>(t));
area.push_back(0x00); // SoundMode
area.push_back(0x00); area.push_back(0x00); // 保留
area.push_back(0x02); // 多行
area.push_back(0x01); // 手动换行
area.push_back(0x01); // 静态显示
area.push_back(0x00); // 退出方式
area.push_back(0x02); // 速度
area.push_back(0x0A); // 停留0.5s 单位)
appendLe32(area, static_cast<uint32_t>(text.size()));
area.insert(area.end(), text.begin(), text.end());
return area;
}
std::vector<uint8_t> buildDynamicTextFrame(const std::string& encodedText,
int screenWidth, int lineHeight,
int areaId,
bool expireWhenNotUpdated,
int timeoutSeconds) {
if (screenWidth <= 0 || screenWidth > 0x7fff) return {};
if (lineHeight <= 0) return {};
const std::vector<uint8_t> area = buildArea(encodedText, screenWidth,
/*areaY=*/0, lineHeight, areaId,
expireWhenNotUpdated, timeoutSeconds);
if (area.empty() || area.size() > 0xffff) return {};
std::vector<uint8_t> payload;
payload.push_back(0xA3);
payload.push_back(0x06); // 动态区域下发
payload.push_back(0x01); // 需要 ACK
payload.push_back(0x00); // ProcessMode: 替换
payload.push_back(0x00); // 保留
payload.push_back(0x00); // DeleteAreaNum: 0
payload.push_back(0x01); // AreaNum: 1
appendLe16(payload, static_cast<uint16_t>(area.size()));
payload.insert(payload.end(), area.begin(), area.end());
return makeFrame(payload);
}
std::vector<uint8_t> buildDeleteDynamicAreaFrame(int areaId) {
if (areaId < 0 || areaId > 0xff) return {};
std::vector<uint8_t> payload = {
0xA3, 0x07, 0x01, 0x00, 0x00, 0x01,
static_cast<uint8_t>(areaId)
};
return makeFrame(payload);
}
bool decodeFrame(const std::vector<uint8_t>& frame,
std::vector<uint8_t>& outPhy1,
std::string& error) {
outPhy1.clear();
if (frame.size() < 8 + 14 + 2 + 1 || frame.back() != 0x5A) {
error = "frame too short or missing tail";
return false;
}
for (size_t i = 0; i < 8; ++i) {
if (frame[i] != 0xA5) { error = "header invalid"; return false; }
}
std::vector<uint8_t> body(frame.begin() + 8, frame.end() - 1);
for (size_t i = 0; i < body.size(); ++i) {
uint8_t b = body[i];
if (b == 0xA6 || b == 0x5B) {
if (++i >= body.size()) { error = "truncated escape"; return false; }
uint8_t n = body[i];
if (b == 0xA6) {
if (n == 0x02) outPhy1.push_back(0xA5);
else if (n == 0x01) outPhy1.push_back(0xA6);
else { error = "bad A6 escape"; return false; }
} else {
if (n == 0x02) outPhy1.push_back(0x5A);
else if (n == 0x01) outPhy1.push_back(0x5B);
else { error = "bad 5B escape"; return false; }
}
} else {
outPhy1.push_back(b);
}
}
if (outPhy1.size() < 16) { error = "phy1 too short"; return false; }
std::vector<uint8_t> withoutCrc(outPhy1.begin(), outPhy1.end() - 2);
uint16_t expected = crc16(withoutCrc);
uint16_t actual = static_cast<uint16_t>(outPhy1[outPhy1.size() - 2]) |
static_cast<uint16_t>(outPhy1[outPhy1.size() - 1] << 8);
if (expected != actual) { error = "crc16 mismatch"; return false; }
outPhy1.pop_back(); outPhy1.pop_back();
return true;
}
bool parseScreenDimensions(const std::vector<uint8_t>& phy1,
int& outWidth, int& outHeight,
std::string& error) {
if (phy1.size() < 14 + 13 || phy1[10] != kDeviceType || phy1[11] != kProtocolVersion) {
error = "response header invalid";
return false;
}
std::vector<uint8_t> payload(phy1.begin() + 14, phy1.end());
if (payload.size() < 13 || payload[0] != 0xA2 || payload[1] != 0x0A || payload[2] != 0x00) {
error = "response payload invalid";
return false;
}
outWidth = static_cast<uint16_t>(payload[9]) | (static_cast<uint16_t>(payload[10]) << 8);
outHeight = static_cast<uint16_t>(payload[11]) | (static_cast<uint16_t>(payload[12]) << 8);
if (outWidth == 0 || outHeight == 0) { error = "invalid dimensions"; return false; }
return true;
}
} // namespace led

@ -0,0 +1,48 @@
// led/BX6K1YYProtocol.hpp
// BX-6K1-YY 协议帧构造/解析(移植自 PuAnLED/Onbon/BX6K1YY/BX6K1YYProtocol.cpp去 Qt 依赖)
#ifndef LED_BX6K1YY_PROTOCOL_HPP
#define LED_BX6K1YY_PROTOCOL_HPP
#include <cstdint>
#include <string>
#include <vector>
namespace led {
// 协议常量(来自 BX-6K1-YY 协议文档与 Windows 版实现)
constexpr uint8_t kDeviceType = 0x64; // BX-6K1-YY
constexpr uint8_t kProtocolVersion = 0x02;
constexpr uint16_t kPortDefault = 5005; // BX-6K1-YY 默认 TCP 端口
// 屏幕参数查询payload = A2 0A 01 00 00
std::vector<uint8_t> buildScreenParameterQueryFrame();
// 构造下发文本的动态区域帧payload: A3 06 01 00 00 01 <LE16 areaLen> <area>
std::vector<uint8_t> buildDynamicTextFrame(const std::string& encodedText,
int screenWidth, int lineHeight,
int areaId,
bool expireWhenNotUpdated,
int timeoutSeconds);
// 删除指定动态区域payload: A3 07 01 00 00 01 <areaId>
std::vector<uint8_t> buildDeleteDynamicAreaFrame(int areaId);
// Modbus CRC-16多项式 0xA001低字节在前
uint16_t crc16(const std::vector<uint8_t>& data);
// 把 payload 包成完整帧8×0xA5 + escape(phy1) + 0x5A
std::vector<uint8_t> makeFrame(const std::vector<uint8_t>& payload);
// 解一帧:校验头/尾、转义还原、CRC16解出的 PHY1 写到 outPhy1不含尾部 CRC
bool decodeFrame(const std::vector<uint8_t>& frame,
std::vector<uint8_t>& outPhy1,
std::string& error);
// 从 PHY1 取出屏幕宽高payload[9..10]=width, payload[11..12]=height
bool parseScreenDimensions(const std::vector<uint8_t>& phy1,
int& outWidth, int& outHeight,
std::string& error);
} // namespace led
#endif

@ -0,0 +1,214 @@
// led/Bx6k1YyLedClient.cxx
#include "Bx6k1YyLedClient.hpp"
#include "BX6K1YYProtocol.hpp"
#include <arpa/inet.h>
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <iconv.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <algorithm>
#include <vector>
namespace led {
namespace {
bool encodeUtf8(const std::string& in, const std::string& encoding, std::string& bytes) {
if (encoding.empty() || encoding == "UTF-8" || encoding == "utf-8") {
bytes = in;
return true;
}
iconv_t cd = iconv_open(encoding.c_str(), "UTF-8//IGNORE");
if (cd == reinterpret_cast<iconv_t>(-1)) return false;
size_t inLeft = in.size();
size_t outLeft = in.size() * 4 + 16;
std::vector<char> out(outLeft);
char* inBuf = const_cast<char*>(in.data());
char* outBuf = out.data();
size_t res = iconv(cd, &inBuf, &inLeft, &outBuf, &outLeft);
iconv_close(cd);
if (res == static_cast<size_t>(-1)) return false;
bytes.assign(out.data(), out.size() - outLeft);
return true;
}
bool setNonBlocking(int fd, bool nb) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) return false;
return fcntl(fd, F_SETFL, nb ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0;
}
bool connectWithTimeout(int fd, const sockaddr_in& addr, int timeoutMs) {
int rc = ::connect(fd, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if (rc == 0) return true;
if (errno != EINPROGRESS) return false;
pollfd pfd{fd, POLLOUT, 0};
if (::poll(&pfd, 1, timeoutMs) <= 0) return false;
int err = 0; socklen_t len = sizeof(err);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) return false;
return err == 0;
}
bool sendAll(int fd, const uint8_t* data, size_t len, int timeoutMs) {
size_t sent = 0;
while (sent < len) {
pollfd pfd{fd, POLLOUT, 0};
if (::poll(&pfd, 1, timeoutMs) <= 0) return false;
ssize_t n = ::send(fd, data + sent, len - sent, MSG_NOSIGNAL);
if (n <= 0) return false;
sent += static_cast<size_t>(n);
}
return true;
}
// 收到至少一个 0x5A 字节或超时
bool recvUntilTail(int fd, std::vector<uint8_t>& buf, int timeoutMs) {
uint8_t chunk[1024];
auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeoutMs);
while (true) {
auto now = std::chrono::steady_clock::now();
if (now >= deadline) return !buf.empty();
int wait = static_cast<int>(
std::chrono::duration_cast<std::chrono::milliseconds>(deadline - now).count());
pollfd pfd{fd, POLLIN, 0};
if (::poll(&pfd, 1, wait) <= 0) return !buf.empty();
ssize_t n = ::recv(fd, chunk, sizeof(chunk), 0);
if (n <= 0) return !buf.empty();
buf.insert(buf.end(), chunk, chunk + n);
if (std::find(buf.begin(), buf.end(), 0x5A) != buf.end()) return true;
}
}
} // anonymous namespace
Bx6k1YyLedClient::Bx6k1YyLedClient(Config cfg) : m_cfg(std::move(cfg)) {}
Bx6k1YyLedClient::~Bx6k1YyLedClient() { closeSocket(); }
void Bx6k1YyLedClient::closeSocket() {
if (m_fd >= 0) { ::close(m_fd); m_fd = -1; }
}
bool Bx6k1YyLedClient::ensureConnected(std::string& error) {
if (m_fd >= 0) return true;
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) { error = std::string("socket: ") + std::strerror(errno); return false; }
setNonBlocking(fd, true);
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(m_cfg.port);
if (inet_pton(AF_INET, m_cfg.ip.c_str(), &addr.sin_addr) != 1) {
::close(fd);
error = "bad ip " + m_cfg.ip;
return false;
}
if (!connectWithTimeout(fd, addr, m_cfg.connectTimeoutMs)) {
::close(fd);
error = "connect " + m_cfg.ip + ":" + std::to_string(m_cfg.port) + " failed";
return false;
}
setNonBlocking(fd, false);
int one = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
m_fd = fd;
return true;
}
bool Bx6k1YyLedClient::queryScreenSize(int& outW, int& outH, std::string& error) {
if (m_fd < 0) { error = "not connected"; return false; }
auto frame = buildScreenParameterQueryFrame();
if (!sendAll(m_fd, frame.data(), frame.size(), m_cfg.responseTimeoutMs)) {
error = "send screen query failed"; return false;
}
std::vector<uint8_t> buf;
if (!recvUntilTail(m_fd, buf, m_cfg.responseTimeoutMs)) {
error = "recv screen query timeout"; return false;
}
auto head = std::find(buf.begin(), buf.end(), 0xA5);
if (head == buf.end()) { error = "no head"; return false; }
auto tailIt = std::find(buf.rbegin(), buf.rend(), 0x5A);
if (tailIt == buf.rend()) { error = "no tail"; return false; }
std::vector<uint8_t> phy1;
std::vector<uint8_t> oneFrame(head, tailIt.base());
if (!decodeFrame(oneFrame, phy1, error)) return false;
return parseScreenDimensions(phy1, outW, outH, error);
}
bool Bx6k1YyLedClient::displayText(const std::string& utf8Text, int areaId, std::string& error) {
if (!ensureConnected(error)) return false;
if (m_screenW <= 0 || m_screenH <= 0) {
int w = 0, h = 0;
if (queryScreenSize(w, h, error)) {
m_screenW = w; m_screenH = h;
} else {
// 查询失败:使用回退分辨率,不阻塞刷新
m_screenW = m_cfg.fallbackScreenWidth;
m_screenH = m_cfg.fallbackScreenHeight;
error.clear();
}
}
std::string encoded;
if (!encodeUtf8(utf8Text, m_cfg.textEncoding, encoded)) {
error = "encode failed"; return false;
}
const int lineH = m_screenH; // 单行:使用整屏高度
const bool isTemporary = (areaId == kAreaTemporary);
const int timeoutSec = isTemporary ? kTemporaryTimeoutSec : 0;
const int effectiveArea = (areaId == kAreaDefault) ? kAreaDefault : kAreaTemporary;
std::vector<uint8_t> frame = buildDynamicTextFrame(encoded,
m_screenW, lineH,
effectiveArea,
isTemporary, timeoutSec);
if (frame.empty()) { error = "build frame failed"; return false; }
if (!sendAll(m_fd, frame.data(), frame.size(), m_cfg.responseTimeoutMs)) {
error = "send frame failed"; return false;
}
std::vector<uint8_t> ack;
recvUntilTail(m_fd, ack, m_cfg.responseTimeoutMs); // 吃掉 ACK
// [诊断] 解 ACK 帧并把 PHY1 全打出来,看控制卡是成功还是返回错误码
if (!ack.empty()) {
std::vector<uint8_t> phy1;
std::string decErr;
if (decodeFrame(ack, phy1, decErr)) {
std::fprintf(stderr, "[Led] ACK phy1 (%zu B):", phy1.size());
for (uint8_t b : phy1) std::fprintf(stderr, " %02X", b);
std::fprintf(stderr, "\n");
// BX-6K1-YY ACK payload 通常从 phy1[14] 起payload[5]=ErrorCode0=成功
if (phy1.size() >= 20) {
std::fprintf(stderr, "[Led] ACK payload[5] (ErrorCode) = 0x%02X\n",
phy1[14 + 5]);
}
} else {
std::fprintf(stderr, "[Led] ACK decode failed: %s, raw (%zu B):",
decErr.c_str(), ack.size());
for (uint8_t b : ack) std::fprintf(stderr, " %02X", b);
std::fprintf(stderr, "\n");
}
} else {
std::fprintf(stderr, "[Led] ACK empty (no response from controller)\n");
}
return true;
}
} // namespace led

@ -0,0 +1,55 @@
// led/Bx6k1YyLedClient.hpp
#ifndef LED_BX6K1YY_CLIENT_HPP
#define LED_BX6K1YY_CLIENT_HPP
#include <cstdint>
#include <string>
namespace led {
// 同步 TCP 客户端。displayText() 内部完成:
// 1) 连 TCP2) 用 A2 0A 查屏幕宽高3) 把整段文本按单行下发到指定动态区域。
// areaId = kAreaDefault (0) → 长驻(不超时),用于显示 led.txt 默认内容
// areaId = kAreaTemporary (1) → 60 秒后由控制卡自动删除,用于临时覆盖的 DDS 排队消息
class Bx6k1YyLedClient {
public:
static constexpr int kAreaDefault = 0;
static constexpr int kAreaTemporary = 1;
static constexpr int kTemporaryTimeoutSec = 60;
struct Config {
std::string ip;
uint16_t port = 5005;
int connectTimeoutMs = 1000;
int responseTimeoutMs = 1000;
// 查不到分辨率时的回退值(按工作区 config / 现场屏)
int fallbackScreenWidth = 64;
int fallbackScreenHeight = 32;
// BX-6K1-YY 文本字段按 GBK 发送;如卡固件是 UTF-8 改 "UTF-8"
std::string textEncoding = "GBK";
};
explicit Bx6k1YyLedClient(Config cfg);
~Bx6k1YyLedClient();
Bx6k1YyLedClient(const Bx6k1YyLedClient&) = delete;
Bx6k1YyLedClient& operator=(const Bx6k1YyLedClient&) = delete;
// 失败时不抛异常,把原因写到 error返回 false 时下次调用会重建连接。
// areaId=0 走长驻areaId=1 走 60 秒自删。
bool displayText(const std::string& utf8Text, int areaId, std::string& error);
private:
bool ensureConnected(std::string& error);
bool queryScreenSize(int& outW, int& outH, std::string& error);
void closeSocket();
Config m_cfg;
int m_fd = -1;
int m_screenW = 0;
int m_screenH = 0;
};
} // namespace led
#endif

@ -32,7 +32,7 @@
#include <fastdds/dds/subscriber/SampleInfo.hpp> #include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
@ -56,6 +56,9 @@ SubscriberApp::SubscriberApp(
, license_topic_(nullptr) , license_topic_(nullptr)
, license_reader_(nullptr) , license_reader_(nullptr)
, license_type_(new WeighingSystem::LicenseSnapUpdatePubSubType()) , license_type_(new WeighingSystem::LicenseSnapUpdatePubSubType())
, queuesuccess_topic_(nullptr)
, queuesuccess_reader_(nullptr)
, queuesuccess_type_(new Queue::QueueSuccessPubSubType())
, samples_received_(0) , samples_received_(0)
, stop_(false) , stop_(false)
{ {
@ -76,6 +79,7 @@ SubscriberApp::SubscriberApp(
weightinfook_type_.register_type(participant_); weightinfook_type_.register_type(participant_);
weightinfoerror_type_.register_type(participant_); weightinfoerror_type_.register_type(participant_);
license_type_.register_type(participant_); license_type_.register_type(participant_);
queuesuccess_type_.register_type(participant_);
// Create the subscriber // Create the subscriber
SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT;
@ -193,6 +197,32 @@ SubscriberApp::SubscriberApp(
{ {
throw std::runtime_error("WeighingSystem::LicenseSnapUpdate DataReader initialization failed"); throw std::runtime_error("WeighingSystem::LicenseSnapUpdate DataReader initialization failed");
} }
// 上位机发的 QueueSuccess → LED 取 display_text 显示
topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos);
queuesuccess_topic_ = participant_->create_topic("QueueSuccess", queuesuccess_type_.get_type_name(), topic_qos);
if (queuesuccess_topic_ == nullptr)
{
throw std::runtime_error("Queue::QueueSuccess Topic initialization failed");
}
reader_qos = DATAREADER_QOS_DEFAULT;
subscriber_->get_default_datareader_qos(reader_qos);
reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
reader_qos.reliability().max_blocking_time = Duration_t(1, 0);
reader_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
reader_qos.history().depth = 1;
reader_qos.resource_limits().max_samples = 200;
reader_qos.resource_limits().max_instances = 1;
reader_qos.resource_limits().max_samples_per_instance = 100;
reader_qos.data_sharing().off();
queuesuccess_reader_ = subscriber_->create_datareader(queuesuccess_topic_, reader_qos, this, StatusMask::all());
if (queuesuccess_reader_ == nullptr)
{
throw std::runtime_error("Queue::QueueSuccess DataReader initialization failed");
}
} }
SubscriberApp::~SubscriberApp() SubscriberApp::~SubscriberApp()
@ -292,6 +322,21 @@ void SubscriberApp::on_data_available(
} }
} }
} }
else if (topic_name == "QueueSuccess")
{
Queue::QueueSuccess sample_;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{
if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data)
{
{
std::unique_lock<std::mutex> lock(DdsMsgData::queue_cv_mtx_);
DdsMsgData::QueueSuccess_queue_.push(std::move(sample_));
lock.unlock();
}
}
}
}
} }
void SubscriberApp::run() void SubscriberApp::run()

@ -29,7 +29,7 @@
#include <fastdds/dds/subscriber/DataReaderListener.hpp> #include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp> #include <fastdds/dds/topic/TypeSupport.hpp>
#include "System.hpp" #include "WeighingDDSType.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{ {
@ -75,6 +75,9 @@ private:
eprosima::fastdds::dds::Topic* license_topic_; eprosima::fastdds::dds::Topic* license_topic_;
eprosima::fastdds::dds::DataReader* license_reader_; eprosima::fastdds::dds::DataReader* license_reader_;
eprosima::fastdds::dds::TypeSupport license_type_; eprosima::fastdds::dds::TypeSupport license_type_;
eprosima::fastdds::dds::Topic* queuesuccess_topic_; // 上位机发的 QueueSuccess让 LED 拿到 display_text
eprosima::fastdds::dds::DataReader* queuesuccess_reader_;
eprosima::fastdds::dds::TypeSupport queuesuccess_type_;
uint16_t samples_received_; uint16_t samples_received_;
std::atomic<bool> stop_; std::atomic<bool> stop_;
mutable std::mutex terminate_cv_mtx_; mutable std::mutex terminate_cv_mtx_;

@ -41,7 +41,6 @@ extern "C" {
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
LEDNETSDK_API int _CALL_STD init_sdk(); LEDNETSDK_API int _CALL_STD init_sdk();
LEDNETSDK_API int _CALL_STD release_sdk(); LEDNETSDK_API int _CALL_STD release_sdk();
#endif #endif

@ -33,10 +33,12 @@
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "YQNetCom.h" #include "BX6K1YYProtocol.hpp"
#include "Bx6k1YyLedClient.hpp"
using eprosima::fastdds::dds::Log; using eprosima::fastdds::dds::Log;
std::function<void(int)> stop_handler; std::function<void(int)> stop_handler;
void signal_handler( void signal_handler(
int signum) int signum)
@ -64,164 +66,17 @@ std::string parse_signal(
} }
} }
static const std::string base64_chars = // ========== LED 运行参数(参照 PuAnLED/Onbon/BX6K1YY 协议BX-6K1-YY0x64 / 0x02==========
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 屏幕宽高是「查询失败时」的回退值;正常情况下启动后通过 A2 0A 查控制卡真实分辨率。
"abcdefghijklmnopqrstuvwxyz" constexpr int LED_SCREEN_WIDTH = 64;
"0123456789+/"; constexpr int LED_SCREEN_HEIGHT = 32;
// 控制卡 IP / 端口(与 config.json.led 对应)
static inline bool is_base64(unsigned char c) { constexpr const char* LED_IP = "192.168.6.147";
return (isalnum(c) || (c == '+') || (c == '/')); constexpr int LED_PORT = 5005;
}
std::string base64_encode(const std::string &input)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
size_t in_len = input.size();
const char *bytes_to_encode = input.c_str();
while (in_len--)
{
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; i < 4; i++)
{
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; j < i + 1; j++)
{
ret += base64_chars[char_array_4[j]];
}
while (i++ < 3)
{
ret += '=';
}
}
return ret;
}
void send_text(std::string ip_addr, int port, std::string text)
{
char *user_name = "guest", *user_pwd = "guest";
int dynamic_type = 1;
int display_effects = 0;
int display_speed = 16;
int stay_time = 10;
int gif_flag = 0;
char *bg_color = "0xff000000";
char *color = "0xffffffff";
char *font_attributes = "normal";
char *font = "SimSun";
char *align_h = "0";
char *align_v = "0";
char *ali = "";
int err;
std::vector<char> ip(ip_addr.begin(), ip_addr.end());
ip.push_back('\0');
std::string wcstring = base64_encode(text);
int b = check_time(ip.data(), port, user_name, user_pwd);
DEBUG("check_time==" << b);
unsigned long play_list = create_playlist(128, 128, 8280);
printf("create_playlist: %p\n", play_list);
char *program_name = "program_0";
unsigned long program = create_program(program_name, bg_color);
printf("create_program: %p\n", program);
unsigned long dynamic_area = create_dynamic();
printf("create_dynamic: %p\n", dynamic_area);
err = add_dynamic_unit(dynamic_area, dynamic_type, display_effects, display_speed, stay_time, wcstring.data(), gif_flag, bg_color, 14, font, color, font_attributes, align_h, align_v, 0, 0, 0, "", "", 0);
DEBUG("add_dynamic_unit:" << err);
err = add_dynamic(program, dynamic_area, 0, 0, 0, 128, 128, ali, 0, ali, 100);
DEBUG("add_dynamic:" << err);
delete_dynamic(dynamic_area);
err = add_program_in_playlist(play_list, program, 0, 10, ali, ali, ali, ali, 127);
DEBUG("add_program_in_playlist:" << err);
err = update_dynamic_small(ip.data(), port, user_name, user_pwd, play_list, "", 1, 0);
if (err != 0)
{
DEBUG(ip.data() << "update_dynamic_small:" << err);
}
delete_playlist(play_list);
}
void send_file(std::string ip_addr, int port, std::string wcstring) // 全局 LED 客户端BX-6K1-YY 协议main 中构造send_text 内部调用
{ static led::Bx6k1YyLedClient* g_led_client = nullptr;
char *user_name = "guest", *user_pwd = "guest";
int dynamic_type = 1;
int display_effects = 0;
int display_speed = 16;
int stay_time = 10;
int gif_flag = 0;
char *bg_color = "0xff000000";
char *color = "0xffffffff";
char *font_attributes = "normal";
char *font = "SimSun";
char *align_h = "0";
char *align_v = "0";
char *ali = "";
int err;
std::vector<char> ip(ip_addr.begin(), ip_addr.end());
ip.push_back('\0');
int b = check_time(ip.data(), port, user_name, user_pwd);
DEBUG("check_time==" << b);
unsigned long play_list = create_playlist(128, 128, 8280);
printf("create_playlist: %p\n", play_list);
char *program_name = "program_0";
unsigned long program = create_program(program_name, bg_color);
printf("create_program: %p\n", program);
unsigned long dynamic_area = create_dynamic();
printf("create_dynamic: %p\n", dynamic_area);
err = add_dynamic_unit(dynamic_area, dynamic_type, display_effects, display_speed, stay_time, wcstring.data(), gif_flag, bg_color, 14, font, color, font_attributes, align_h, align_v, 0, 0, 0, "", "", 0);
DEBUG("add_dynamic_unit:" << err);
err = add_dynamic(program, dynamic_area, 0, 0, 0, 128, 128, ali, 0, ali, 100);
DEBUG("add_dynamic:" << err);
delete_dynamic(dynamic_area);
err = add_program_in_playlist(play_list, program, 0, 10, ali, ali, ali, ali, 127);
DEBUG("add_program_in_playlist:" << err);
err = update_dynamic(ip.data(), port, user_name, user_pwd, play_list, "", 1, 0);
if (err != 0)
{
DEBUG(ip.data() << "update_dynamic:" << err);
}
delete_playlist(play_list);
}
std::string readfile(std::string name) std::string readfile(std::string name)
{ {
@ -251,10 +106,33 @@ std::string readfile(std::string name)
return config; return config;
} }
// 默认内容led.txt长驻到 area 0控制卡不会自动删除。
static void send_default_text(const std::string& text)
{
if (!g_led_client) return;
std::string err;
if (!g_led_client->displayText(text, led::Bx6k1YyLedClient::kAreaDefault, err))
{
std::cerr << "LED default display failed: " << err << std::endl;
}
}
// DDS QueueSuccess 消息:下发到 area 160 秒后由控制卡自动删除,露出 area 0 的默认内容。
static void send_queue_text(const std::string& text)
{
if (!g_led_client) return;
std::string err;
if (!g_led_client->displayText(text, led::Bx6k1YyLedClient::kAreaTemporary, err))
{
std::cerr << "LED queue display failed: " << err << std::endl;
}
}
std::queue<WeighingSystem::ScaleInfo> DdsMsgData::ScaleInfo_queue_; std::queue<WeighingSystem::ScaleInfo> DdsMsgData::ScaleInfo_queue_;
std::queue<WeighingSystem::WeightInfoOk> DdsMsgData::WeightInfoOk_queue_; std::queue<WeighingSystem::WeightInfoOk> DdsMsgData::WeightInfoOk_queue_;
std::queue<WeighingSystem::WeightInfoError> DdsMsgData::WeightInfoError_queue_; std::queue<WeighingSystem::WeightInfoError> DdsMsgData::WeightInfoError_queue_;
std::queue<WeighingSystem::LicenseSnapUpdate> DdsMsgData::LicenseSnapUpdate_queue_; std::queue<WeighingSystem::LicenseSnapUpdate> DdsMsgData::LicenseSnapUpdate_queue_;
std::queue<Queue::QueueSuccess> DdsMsgData::QueueSuccess_queue_;
std::mutex DdsMsgData::queue_cv_mtx_; std::mutex DdsMsgData::queue_cv_mtx_;
std::atomic<bool> running(true); std::atomic<bool> running(true);
@ -265,13 +143,12 @@ int main(int argc, char** argv)
std::shared_ptr<SubscriberApp> sub; std::shared_ptr<SubscriberApp> sub;
int domain_id = 0; int domain_id = 0;
int port = 80;
int type = 0;
std::string addr = "192.168.1.100";
uint8_t clear_led = 1;
uint8_t weight_stable = 0;
std::string license = "";
// —— IP / 端口:命令行可覆盖顶部常量 ——
std::string addr = LED_IP;
int port = LED_PORT;
// ====== 命令行解析 ======
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
{ {
if (strcmp(argv[i], "--domain") == 0 && i + 1 < argc) if (strcmp(argv[i], "--domain") == 0 && i + 1 < argc)
@ -281,152 +158,117 @@ int main(int argc, char** argv)
else if (strcmp(argv[i], "--addr") == 0 && i + 1 < argc) else if (strcmp(argv[i], "--addr") == 0 && i + 1 < argc)
{ {
addr = argv[++i]; addr = argv[++i];
DEBUG("use addr from cmd: " << addr);
} }
else if (strcmp(argv[i], "--port") == 0 && i + 1 < argc) else if (strcmp(argv[i], "--port") == 0 && i + 1 < argc)
{ {
port = atoi(argv[++i]); port = atoi(argv[++i]);
} DEBUG("use port from cmd: " << port);
else if (strcmp(argv[i], "--type") == 0 && i + 1 < argc)
{
type = atoi(argv[++i]);
} }
else if (strcmp(argv[i], "--version") == 0) else if (strcmp(argv[i], "--version") == 0)
{ {
std::cout << "Vesrion: " << PROGRAM_VERSION << "\n"; std::cout << "Version: " << PROGRAM_VERSION << "\n";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
else if (strcmp(argv[i], "--help") == 0) else if (strcmp(argv[i], "--help") == 0)
{ {
std::cout << "Usage: [options]\n" std::cout << "Usage: led [options]\n"
<< "Options:\n" << "Options:\n"
<< " --domain Set domain ID\n" << " --domain Set DDS domain ID\n"
<< " --addr Set led addr (e.g., 192.168.1.1)\n" << " --addr LED TCP ip\n"
<< " --port Set port name (e.g., 80)\n" << " --port LED TCP port (default " << LED_PORT << ")\n"
<< " --type Set port name (0: in car, 1: not in car)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n"
<< "\nLED config (edit source):\n"
<< " ip = " << LED_IP << "\n"
<< " port = " << port << "\n"
<< " screen = " << LED_SCREEN_WIDTH << "x" << LED_SCREEN_HEIGHT
<< " (fallback; real size queried at runtime via A2 0A)\n"
<< " protocol = BX-6K1-YY (0x64 / 0x02), A3 06 dynamic area\n";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
else else
{ {
std::cerr << "Unknown option: " << argv[i] << "\n"; std::cout << "Usage: led [options]\n"
std::cout << "Usage: [options]\n" << " --domain Set DDS domain ID\n"
<< "Options:\n"
<< " --domain Set domain ID\n"
<< " --addr Set led addr (e.g., 192.168.1.1)\n"
<< " --port Set port name (e.g., 80)\n"
<< " --type Set port name (0: in car, 1: not in car)\n"
<< " --version Show software Version\n" << " --version Show software Version\n"
<< " --help Show this help message\n"; << " --help Show this help message\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
sub = std::make_shared<SubscriberApp>(domain_id); // ====== 0. 构造 BX-6K1-YY LED 客户端(裸 TCP 协议,不依赖 vendor SDK======
{
led::Bx6k1YyLedClient::Config cfg;
cfg.ip = addr;
cfg.port = static_cast<uint16_t>(port);
cfg.connectTimeoutMs = 1000;
cfg.responseTimeoutMs = 1000;
cfg.fallbackScreenWidth = LED_SCREEN_WIDTH;
cfg.fallbackScreenHeight = LED_SCREEN_HEIGHT;
// cfg.textEncoding = "GBK"; // BX-6K1-YY 默认按 GBK
cfg.textEncoding = "UTF-8"; // 临时:跳过 iconv先验证连通和协议
g_led_client = new led::Bx6k1YyLedClient(cfg);
}
// ====== 1. DDS 订阅 ======
sub = std::make_shared<SubscriberApp>(domain_id);
DEBUG("Program is running. Please press Ctrl+C to stop at any time."); DEBUG("Program is running. Please press Ctrl+C to stop at any time.");
auto formatFloat = [](float value) -> std::string // ====== 2. 启动直接显示默认内容(长驻 area 0======
{ const std::string default_text = "#3排队"; // UTF-8 → iconv 转 GBK = 23 33 C5 C5 B6 D3
std::ostringstream oss; send_default_text(default_text);
oss << std::fixed << std::setprecision(2) << value;
return oss.str();
};
std::string default_text = readfile("led.txt"); // ====== 3. 主循环:仅 QueueSuccess 触发刷新,下发到 area 160 秒自删)======
send_text(addr, port, default_text); std::string last_text;
bool last_inited = false;
while (running.load()) while (running.load())
{ {
std::unique_lock<std::mutex> lock(DdsMsgData::queue_cv_mtx_, std::try_to_lock); std::unique_lock<std::mutex> lock(DdsMsgData::queue_cv_mtx_, std::try_to_lock);
if (lock.owns_lock()) if (lock.owns_lock())
{ {
if(!DdsMsgData::WeightInfoOk_queue_.empty()) if (!DdsMsgData::QueueSuccess_queue_.empty())
{
WeighingSystem::WeightInfoOk info = std::move(DdsMsgData::WeightInfoOk_queue_.front());
DdsMsgData::WeightInfoOk_queue_.pop();
lock.unlock();
send_text(addr, port, info.Warning());
clear_led = 0;
}
else if (!DdsMsgData::WeightInfoError_queue_.empty())
{
WeighingSystem::WeightInfoError info = std::move(DdsMsgData::WeightInfoError_queue_.front());
DdsMsgData::WeightInfoError_queue_.pop();
lock.unlock();
send_text(addr, port, info.Warning());
clear_led = 0;
}
else if (!DdsMsgData::ScaleInfo_queue_.empty())
{ {
WeighingSystem::ScaleInfo info = std::move(DdsMsgData::ScaleInfo_queue_.front()); Queue::QueueSuccess info = std::move(DdsMsgData::QueueSuccess_queue_.front());
DdsMsgData::ScaleInfo_queue_.pop(); DdsMsgData::QueueSuccess_queue_.pop();
lock.unlock(); lock.unlock();
if (info.HasVehicle() == false) std::string cur = info.display_text();
{ if (!last_inited || cur != last_text)
if (clear_led == 0)
{ {
send_text(addr, port, default_text); last_text = cur;
clear_led = 1; last_inited = true;
license.clear(); DEBUG("QueueSuccess.display_text=" << cur);
send_queue_text(cur);
} }
} }
if (info.WeightOK() == true)
{
weight_stable = 1;
}
else else
{ {
weight_stable = 0;
}
}
else if (!DdsMsgData::LicenseSnapUpdate_queue_.empty())
{
WeighingSystem::LicenseSnapUpdate info = std::move(DdsMsgData::LicenseSnapUpdate_queue_.front());
DdsMsgData::LicenseSnapUpdate_queue_.pop();
lock.unlock(); lock.unlock();
license = info.License();
weight_stable = 0;
} }
else
{
lock.unlock();
} }
std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
if (type == 1) // ====== 4. 退出:释放 LED 客户端 ======
if (g_led_client)
{ {
if ((weight_stable == 1) && (!license.empty())) delete g_led_client;
{ g_led_client = nullptr;
std::string text = license + std::string(",司机请下车等候,切勿停留在车上!");
send_text(addr, port, text);
clear_led = 0;
weight_stable = 0;
license.clear();
}
} }
std::this_thread::sleep_for(std::chrono::milliseconds(100)); stop_handler = [&](int signum) {
} std::cout << "\n" << parse_signal(signum) << " received, stopping "
<< (argc > 0 ? argv[0] : "") << " execution." << std::endl;
stop_handler = [&](int signum)
{
std::cout << "\n" << parse_signal(signum) << " received, stopping " << argv[1]
<< " execution." << std::endl;
running.store(false); running.store(false);
}; };
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);
#ifndef _WIN32 #ifndef _WIN32
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
signal(SIGHUP, signal_handler); signal(SIGHUP, signal_handler);
#endif // _WIN32 #endif
Log::Reset(); Log::Reset();
return ret; return ret;

@ -3,7 +3,7 @@
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#include "System.hpp" #include "WeighingDDSType.hpp"
class DdsMsgData { class DdsMsgData {
public: public:
@ -11,6 +11,7 @@ public:
static std::queue<WeighingSystem::WeightInfoOk> WeightInfoOk_queue_; static std::queue<WeighingSystem::WeightInfoOk> WeightInfoOk_queue_;
static std::queue<WeighingSystem::WeightInfoError> WeightInfoError_queue_; static std::queue<WeighingSystem::WeightInfoError> WeightInfoError_queue_;
static std::queue<WeighingSystem::LicenseSnapUpdate> LicenseSnapUpdate_queue_; static std::queue<WeighingSystem::LicenseSnapUpdate> LicenseSnapUpdate_queue_;
static std::queue<Queue::QueueSuccess> QueueSuccess_queue_; // 上位机下发LED 取 display_text 显示
static std::mutex queue_cv_mtx_; static std::mutex queue_cv_mtx_;
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -73,6 +73,12 @@ module WeighingSystem {
// 打印磅单相关 // 打印磅单相关
string TicketType; // 磅单类型 1:一次称重 2:二次称重 string TicketType; // 磅单类型 1:一次称重 2:二次称重
boolean IsPrintTicker; // 是否打印磅单 boolean IsPrintTicker; // 是否打印磅单
// 绥阳铁合金称重成功扩展属性
string OrderNumber; // 订单号
string VehicleAndVesselNumber; // 车船号
string ReceiveCompany; // 收货单位
string TransportCompany; // 运输单位
}; };
// ============================================ // ============================================
@ -193,34 +199,153 @@ module WeighingSystem {
// 称重类 // 称重类
// ============================================ // ============================================
struct SummaryUpdate { struct SummaryUpdate {
string License; // 车牌号 string License; // 五彩湾为车牌号;绥阳铁合金为刷卡卡号
float StableValue; // 稳定重量 float StableValue; // 稳定重量;绥阳铁合金按吨传输
}; };
// ============================================
// Topic: ReadCardReq <-- 订阅 Topic (设备驱动侧)
// 类型: ReadCardReq
// 发布者: Core
// 订阅者: ReadCard
// 载荷: map<string, sequence<octet>>
// 协议键: "find" / "stop" / "read" / "write" / "beep" / "reset"
// ============================================
struct ReadCardReq
{
unsigned long index;
map<string, sequence<octet> > msg;
}; };
module InternalSystem // ============================================
// Topic: ReadCardRsp <-- 发布 Topic (设备驱动侧)
// 类型: ReadCardRsp
// 发布者: ReadCard
// 订阅者: Core / MqttDds
// 载荷: map<string, sequence<octet>>
// 协议键: "find" / "read" / "write" / "stop" / "beep"
// ============================================
struct ReadCardRsp
{ {
unsigned long index;
map<string, sequence<octet> > msg;
};
// ============================================
// Topic: PrintReq <-- 发布 Topic (Core → Print)
// 类型: PrintReq
// 发布者: Core
// 订阅者: Print
// 载荷: map<string, string>
// ============================================
struct PrintReq struct PrintReq
{ {
unsigned long index; unsigned long index;
map<string, string> msg; map<string, string> msg;
}; };
// ============================================
// Topic: PrintRsp <-- 发布 Topic (Print → Core)
// 类型: PrintRsp
// 发布者: Print
// 订阅者: Core
// 载荷: string
// ============================================
struct PrintRsp struct PrintRsp
{ {
unsigned long index; unsigned long index;
string msg; string msg;
}; };
};
struct IoCtrlReq // ============================================
{ // 通用排队服务消息
unsigned long index; // 排队设备通过 QueueTrigger 触发服务,服务发布 Success/Failure 结果。
map<string, string> msg; // ============================================
module Queue {
// 排队机刷卡触发。只表达设备刷到的卡,不携带服务内部缓存定位字段。
struct QueueTrigger {
string message_id; // 可选技术消息号;重发时保持不变
string card_number; // 必填;刷卡得到的卡号
string device_id; // 必填;排队机/读卡器统一设备编号
string trigger_time; // 可选ISO-8601时间仅用于审计和去重
string vehicle_number_snapshot; // 可选;控件车牌快照,仅用于一致性校验
long supplier_identity_id_snapshot;// 可选0表示未提供
long goods_id_snapshot; // 可选0表示未提供
float ship_net_weight_snapshot; // 可选0表示未提供
long card_flow_no_snapshot; // 可选0表示未提供
string card_type_snapshot; // 可选;卡类型快照
string electronic_tag_snapshot; // 可选;电子标签由排队设备读取后传递
}; };
struct IoCtrlRsp // 排队成功或活动记录补打成功结果。
{ struct QueueSuccess {
unsigned long index; string message_id; // 可选;技术消息号
map<string, string> msg; string card_number; // 必填;触发卡号
string device_id; // 必填;结果目标设备
long result_code; // 必填0新排队1补打
long queue_record_id; // 排队_列表主键
long queue_number; // 排队序号
string sample_machine; // 采样机名称
string queue_time; // 排入时间
string ticket_number; // 进煤表票据号
long sample_code; // 采样编码
string vehicle_number; // 正式车牌
long vehicle_self_no; // 车辆自编号
long vehicle_type_id; // 车型编号
long supplier_identity_id; // 供应识别号
string supplier_identity_name; // 供应识别名称
long supplier_id; // 供应商主键
string supplier_name; // 供应商名称
long goods_id; // 品种编号
string goods_name; // 品种名称
long unit_id; // 单位编号
long transport_company_id; // 运输公司编号
long sample_type; // 采样类型
string unloading_point_name; // 卸煤点名称
float ship_gross_weight; // 矿发毛重
float ship_tare_weight; // 矿发皮重
float ship_net_weight; // 矿发净重
long sample_machine_id; // 采样机编号无值为0
string vehicle_lane; // 车道名称
long vehicle_lane_id; // 车道编号无值为0
string strategy_desc; // 排队策略说明
string committed_at; // 数据库提交时间
string display_text; // 显示文本
string print_content; // 打印内容
boolean print_required; // 是否打印
long print_count; // 打印份数
long voice_id; // 语音资源编号
string voice_text; // 语音播报文本
boolean is_reprint; // 是否补打
string physical_card_state; // NOT_ATTEMPTED/CHANGED/PARTIAL
string card_write_status; // DISABLED/SUCCEEDED/FAILED/PARTIAL
};
// 排队失败结果。数据库已提交但事务外动作失败时仍携带已生成的业务编号。
struct QueueFailure {
string message_id; // 可选;技术消息号
string card_number; // 可解析时的卡号
string device_id; // 可识别时的设备编号
string error_code; // 必填;机器可判定错误码
string failed_step; // 必填;失败步骤
string message; // 必填;显示/告警文本
string vehicle_number; // 缓存车牌(可选)
long queue_record_id; // 已提交排队记录主键无记录为0
long queue_number; // 已生成排队号无记录为0
string sample_machine; // 已分配采样机
string ticket_number; // 已生成票据号
long existing_queue_record_id; // 活动排队记录主键
long existing_queue_number; // 活动排队号
string existing_sample_machine; // 活动采样机
string cache_state; // 缓存状态
string database_state; // NOT_ATTEMPTED/COMMITTED/ROLLED_BACK/UNKNOWN
string physical_card_state; // NOT_ATTEMPTED/CHANGED/UNCHANGED/PARTIAL/UNKNOWN
boolean retryable; // 是否允许同一触发重试
long retry_after_ms; // 建议重试等待时间
long voice_id; // 语音资源编号
string voice_text; // 语音播报文本
string card_write_status; // DISABLED/SUCCEEDED/FAILED/PARTIAL
}; };
}; };

@ -13,68 +13,77 @@
// limitations under the License. // limitations under the License.
/*! /*!
* @file SystemCdrAux.hpp * @file WeighingDDSTypeCdrAux.hpp
* This source file contains some definitions of CDR related functions. * This source file contains some definitions of CDR related functions.
* *
* This file was generated by the tool fastddsgen. * This file was generated by the tool fastddsgen.
*/ */
#ifndef FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEMCDRAUX_HPP #ifndef FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPECDRAUX_HPP
#define FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEMCDRAUX_HPP #define FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPECDRAUX_HPP
#include "System.hpp" #include "WeighingDDSType.hpp"
constexpr uint32_t WeighingSystem_PrintRsp_max_cdr_typesize {268UL};
constexpr uint32_t WeighingSystem_PrintRsp_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_SummaryUpdate_max_cdr_typesize {268UL}; constexpr uint32_t WeighingSystem_SummaryUpdate_max_cdr_typesize {268UL};
constexpr uint32_t WeighingSystem_SummaryUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_SummaryUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t Queue_QueueFailure_max_cdr_typesize {3932UL};
constexpr uint32_t Queue_QueueFailure_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_LightsUpdate_max_cdr_typesize {12UL}; constexpr uint32_t WeighingSystem_LightsUpdate_max_cdr_typesize {12UL};
constexpr uint32_t WeighingSystem_LightsUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_LightsUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_InfraredUpdate_max_cdr_typesize {12UL}; constexpr uint32_t WeighingSystem_InfraredUpdate_max_cdr_typesize {12UL};
constexpr uint32_t WeighingSystem_InfraredUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_InfraredUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t InternalSystem_PrintReq_max_cdr_typesize {16UL}; constexpr uint32_t WeighingSystem_ReadCardRsp_max_cdr_typesize {16UL};
constexpr uint32_t InternalSystem_PrintReq_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_ReadCardRsp_max_key_cdr_typesize {0UL};
constexpr uint32_t Queue_QueueSuccess_max_cdr_typesize {5028UL};
constexpr uint32_t Queue_QueueSuccess_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_WeightInfoError_max_cdr_typesize {524UL}; constexpr uint32_t WeighingSystem_WeightInfoError_max_cdr_typesize {524UL};
constexpr uint32_t WeighingSystem_WeightInfoError_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_WeightInfoError_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_WeightInfoOk_max_cdr_typesize {4977UL}; constexpr uint32_t WeighingSystem_WeightInfoOk_max_cdr_typesize {6020UL};
constexpr uint32_t WeighingSystem_WeightInfoOk_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_WeightInfoOk_max_key_cdr_typesize {0UL};
constexpr uint32_t InternalSystem_IoCtrlRsp_max_cdr_typesize {16UL};
constexpr uint32_t InternalSystem_IoCtrlRsp_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_InfraredCommandUpdate_max_cdr_typesize {17UL}; constexpr uint32_t WeighingSystem_InfraredCommandUpdate_max_cdr_typesize {17UL};
constexpr uint32_t WeighingSystem_InfraredCommandUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_InfraredCommandUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_LightsCommandUpdate_max_cdr_typesize {20UL}; constexpr uint32_t WeighingSystem_LightsCommandUpdate_max_cdr_typesize {20UL};
constexpr uint32_t WeighingSystem_LightsCommandUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_LightsCommandUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_ReadCardReq_max_cdr_typesize {16UL};
constexpr uint32_t WeighingSystem_ReadCardReq_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_PrintReq_max_cdr_typesize {16UL};
constexpr uint32_t WeighingSystem_PrintReq_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_LicenseSnapUpdate_max_cdr_typesize {268UL}; constexpr uint32_t WeighingSystem_LicenseSnapUpdate_max_cdr_typesize {268UL};
constexpr uint32_t WeighingSystem_LicenseSnapUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_LicenseSnapUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_ScaleInfo_max_cdr_typesize {16UL}; constexpr uint32_t WeighingSystem_ScaleInfo_max_cdr_typesize {16UL};
constexpr uint32_t WeighingSystem_ScaleInfo_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_ScaleInfo_max_key_cdr_typesize {0UL};
constexpr uint32_t InternalSystem_PrintRsp_max_cdr_typesize {268UL};
constexpr uint32_t InternalSystem_PrintRsp_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_Voice_max_cdr_typesize {268UL}; constexpr uint32_t WeighingSystem_Voice_max_cdr_typesize {268UL};
constexpr uint32_t WeighingSystem_Voice_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_Voice_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_BarCommandUpdate_max_cdr_typesize {25UL}; constexpr uint32_t WeighingSystem_BarCommandUpdate_max_cdr_typesize {25UL};
constexpr uint32_t WeighingSystem_BarCommandUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_BarCommandUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t Queue_QueueTrigger_max_cdr_typesize {1840UL};
constexpr uint32_t Queue_QueueTrigger_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_ScaleCommand_max_cdr_typesize {12UL}; constexpr uint32_t WeighingSystem_ScaleCommand_max_cdr_typesize {12UL};
constexpr uint32_t WeighingSystem_ScaleCommand_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_ScaleCommand_max_key_cdr_typesize {0UL};
constexpr uint32_t WeighingSystem_BarUpdate_max_cdr_typesize {12UL}; constexpr uint32_t WeighingSystem_BarUpdate_max_cdr_typesize {12UL};
constexpr uint32_t WeighingSystem_BarUpdate_max_key_cdr_typesize {0UL}; constexpr uint32_t WeighingSystem_BarUpdate_max_key_cdr_typesize {0UL};
constexpr uint32_t InternalSystem_IoCtrlReq_max_cdr_typesize {16UL};
constexpr uint32_t InternalSystem_IoCtrlReq_max_key_cdr_typesize {0UL};
namespace eprosima { namespace eprosima {
namespace fastcdr { namespace fastcdr {
@ -136,23 +145,35 @@ eProsima_user_DllExport void serialize_key(
eProsima_user_DllExport void serialize_key( eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr, eprosima::fastcdr::Cdr& scdr,
const InternalSystem::PrintReq& data); const WeighingSystem::ReadCardReq& data);
eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr,
const WeighingSystem::ReadCardRsp& data);
eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr,
const WeighingSystem::PrintReq& data);
eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr,
const WeighingSystem::PrintRsp& data);
eProsima_user_DllExport void serialize_key( eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr, eprosima::fastcdr::Cdr& scdr,
const InternalSystem::PrintRsp& data); const Queue::QueueTrigger& data);
eProsima_user_DllExport void serialize_key( eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr, eprosima::fastcdr::Cdr& scdr,
const InternalSystem::IoCtrlReq& data); const Queue::QueueSuccess& data);
eProsima_user_DllExport void serialize_key( eProsima_user_DllExport void serialize_key(
eprosima::fastcdr::Cdr& scdr, eprosima::fastcdr::Cdr& scdr,
const InternalSystem::IoCtrlRsp& data); const Queue::QueueFailure& data);
} // namespace fastcdr } // namespace fastcdr
} // namespace eprosima } // namespace eprosima
#endif // FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEMCDRAUX_HPP #endif // FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPECDRAUX_HPP

File diff suppressed because it is too large Load Diff

@ -13,19 +13,19 @@
// limitations under the License. // limitations under the License.
/*! /*!
* @file SystemPubSubTypes.cpp * @file WeighingDDSTypePubSubTypes.cpp
* This header file contains the implementation of the serialization functions. * This header file contains the implementation of the serialization functions.
* *
* This file was generated by the tool fastddsgen. * This file was generated by the tool fastddsgen.
*/ */
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include <fastdds/dds/log/Log.hpp> #include <fastdds/dds/log/Log.hpp>
#include <fastdds/rtps/common/CdrSerialization.hpp> #include <fastdds/rtps/common/CdrSerialization.hpp>
#include "SystemCdrAux.hpp" #include "WeighingDDSTypeCdrAux.hpp"
#include "SystemTypeObjectSupport.hpp" #include "WeighingDDSTypeTypeObjectSupport.hpp"
using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t;
using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t;
@ -2398,17 +2398,378 @@ namespace WeighingSystem {
register_SummaryUpdate_type_identifier(type_identifiers_); register_SummaryUpdate_type_identifier(type_identifiers_);
} }
} // namespace WeighingSystem ReadCardReqPubSubType::ReadCardReqPubSubType()
{
set_name("WeighingSystem::ReadCardReq");
uint32_t type_size = WeighingSystem_ReadCardReq_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false;
uint32_t key_length = WeighingSystem_ReadCardReq_max_key_cdr_typesize > 16 ? WeighingSystem_ReadCardReq_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length);
}
ReadCardReqPubSubType::~ReadCardReqPubSubType()
{
if (key_buffer_ != nullptr)
{
free(key_buffer_);
}
}
bool ReadCardReqPubSubType::serialize(
const void* const data,
SerializedPayload_t& payload,
DataRepresentationId_t data_representation)
{
const ReadCardReq* p_type = static_cast<const ReadCardReq*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2);
payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
ser.set_encoding_flag(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR :
eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2);
try
{
// Serialize encapsulation
ser.serialize_encapsulation();
// Serialize the object.
ser << *p_type;
ser.set_dds_cdr_options({0,0});
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
// Get the serialized length
payload.length = static_cast<uint32_t>(ser.get_serialized_data_length());
return true;
}
bool ReadCardReqPubSubType::deserialize(
SerializedPayload_t& payload,
void* data)
{
try
{
// Convert DATA to pointer of your type
ReadCardReq* p_type = static_cast<ReadCardReq*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
// Object that deserializes the data.
eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN);
// Deserialize encapsulation.
deser.read_encapsulation();
payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
// Deserialize the object.
deser >> *p_type;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
return true;
}
uint32_t ReadCardReqPubSubType::calculate_serialized_size(
const void* const data,
DataRepresentationId_t data_representation)
{
try
{
eprosima::fastcdr::CdrSizeCalculator calculator(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
size_t current_alignment {0};
return static_cast<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const ReadCardReq*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* ReadCardReqPubSubType::create_data()
{
return reinterpret_cast<void*>(new ReadCardReq());
}
void ReadCardReqPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<ReadCardReq*>(data));
}
bool ReadCardReqPubSubType::compute_key(
SerializedPayload_t& payload,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
ReadCardReq data;
if (deserialize(payload, static_cast<void*>(&data)))
{
return compute_key(static_cast<void*>(&data), handle, force_md5);
}
return false;
}
bool ReadCardReqPubSubType::compute_key(
const void* const data,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
const ReadCardReq* p_type = static_cast<const ReadCardReq*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
WeighingSystem_ReadCardReq_max_key_cdr_typesize);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || WeighingSystem_ReadCardReq_max_key_cdr_typesize > 16)
{
md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
md5_.finalize();
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = md5_.digest[i];
}
}
else
{
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = key_buffer_[i];
}
}
return true;
}
void ReadCardReqPubSubType::register_type_object_representation()
{
register_ReadCardReq_type_identifier(type_identifiers_);
}
ReadCardRspPubSubType::ReadCardRspPubSubType()
{
set_name("WeighingSystem::ReadCardRsp");
uint32_t type_size = WeighingSystem_ReadCardRsp_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false;
uint32_t key_length = WeighingSystem_ReadCardRsp_max_key_cdr_typesize > 16 ? WeighingSystem_ReadCardRsp_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length);
}
ReadCardRspPubSubType::~ReadCardRspPubSubType()
{
if (key_buffer_ != nullptr)
{
free(key_buffer_);
}
}
bool ReadCardRspPubSubType::serialize(
const void* const data,
SerializedPayload_t& payload,
DataRepresentationId_t data_representation)
{
const ReadCardRsp* p_type = static_cast<const ReadCardRsp*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2);
payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
ser.set_encoding_flag(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR :
eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2);
try
{
// Serialize encapsulation
ser.serialize_encapsulation();
// Serialize the object.
ser << *p_type;
ser.set_dds_cdr_options({0,0});
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
// Get the serialized length
payload.length = static_cast<uint32_t>(ser.get_serialized_data_length());
return true;
}
bool ReadCardRspPubSubType::deserialize(
SerializedPayload_t& payload,
void* data)
{
try
{
// Convert DATA to pointer of your type
ReadCardRsp* p_type = static_cast<ReadCardRsp*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
// Object that deserializes the data.
eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN);
// Deserialize encapsulation.
deser.read_encapsulation();
payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
// Deserialize the object.
deser >> *p_type;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
return true;
}
uint32_t ReadCardRspPubSubType::calculate_serialized_size(
const void* const data,
DataRepresentationId_t data_representation)
{
try
{
eprosima::fastcdr::CdrSizeCalculator calculator(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
size_t current_alignment {0};
return static_cast<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const ReadCardRsp*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* ReadCardRspPubSubType::create_data()
{
return reinterpret_cast<void*>(new ReadCardRsp());
}
void ReadCardRspPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<ReadCardRsp*>(data));
}
bool ReadCardRspPubSubType::compute_key(
SerializedPayload_t& payload,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
ReadCardRsp data;
if (deserialize(payload, static_cast<void*>(&data)))
{
return compute_key(static_cast<void*>(&data), handle, force_md5);
}
return false;
}
bool ReadCardRspPubSubType::compute_key(
const void* const data,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
const ReadCardRsp* p_type = static_cast<const ReadCardRsp*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
WeighingSystem_ReadCardRsp_max_key_cdr_typesize);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || WeighingSystem_ReadCardRsp_max_key_cdr_typesize > 16)
{
md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
md5_.finalize();
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = md5_.digest[i];
}
}
else
{
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = key_buffer_[i];
}
}
return true;
}
void ReadCardRspPubSubType::register_type_object_representation()
{
register_ReadCardRsp_type_identifier(type_identifiers_);
}
namespace InternalSystem {
PrintReqPubSubType::PrintReqPubSubType() PrintReqPubSubType::PrintReqPubSubType()
{ {
set_name("InternalSystem::PrintReq"); set_name("WeighingSystem::PrintReq");
uint32_t type_size = InternalSystem_PrintReq_max_cdr_typesize; uint32_t type_size = WeighingSystem_PrintReq_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/ max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false; is_compute_key_provided = false;
uint32_t key_length = InternalSystem_PrintReq_max_key_cdr_typesize > 16 ? InternalSystem_PrintReq_max_key_cdr_typesize : 16; uint32_t key_length = WeighingSystem_PrintReq_max_key_cdr_typesize > 16 ? WeighingSystem_PrintReq_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length)); key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length); memset(key_buffer_, 0, key_length);
} }
@ -2552,13 +2913,13 @@ namespace InternalSystem {
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_), eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
InternalSystem_PrintReq_max_key_cdr_typesize); WeighingSystem_PrintReq_max_key_cdr_typesize);
// Object that serializes the data. // Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type); eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || InternalSystem_PrintReq_max_key_cdr_typesize > 16) if (force_md5 || WeighingSystem_PrintReq_max_key_cdr_typesize > 16)
{ {
md5_.init(); md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length())); md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
@ -2585,12 +2946,12 @@ namespace InternalSystem {
PrintRspPubSubType::PrintRspPubSubType() PrintRspPubSubType::PrintRspPubSubType()
{ {
set_name("InternalSystem::PrintRsp"); set_name("WeighingSystem::PrintRsp");
uint32_t type_size = InternalSystem_PrintRsp_max_cdr_typesize; uint32_t type_size = WeighingSystem_PrintRsp_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/ max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false; is_compute_key_provided = false;
uint32_t key_length = InternalSystem_PrintRsp_max_key_cdr_typesize > 16 ? InternalSystem_PrintRsp_max_key_cdr_typesize : 16; uint32_t key_length = WeighingSystem_PrintRsp_max_key_cdr_typesize > 16 ? WeighingSystem_PrintRsp_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length)); key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length); memset(key_buffer_, 0, key_length);
} }
@ -2734,13 +3095,13 @@ namespace InternalSystem {
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_), eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
InternalSystem_PrintRsp_max_key_cdr_typesize); WeighingSystem_PrintRsp_max_key_cdr_typesize);
// Object that serializes the data. // Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type); eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || InternalSystem_PrintRsp_max_key_cdr_typesize > 16) if (force_md5 || WeighingSystem_PrintRsp_max_key_cdr_typesize > 16)
{ {
md5_.init(); md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length())); md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
@ -2765,19 +3126,204 @@ namespace InternalSystem {
register_PrintRsp_type_identifier(type_identifiers_); register_PrintRsp_type_identifier(type_identifiers_);
} }
IoCtrlReqPubSubType::IoCtrlReqPubSubType() } // namespace WeighingSystem
namespace Queue {
QueueTriggerPubSubType::QueueTriggerPubSubType()
{
set_name("Queue::QueueTrigger");
uint32_t type_size = Queue_QueueTrigger_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false;
uint32_t key_length = Queue_QueueTrigger_max_key_cdr_typesize > 16 ? Queue_QueueTrigger_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length);
}
QueueTriggerPubSubType::~QueueTriggerPubSubType()
{
if (key_buffer_ != nullptr)
{
free(key_buffer_);
}
}
bool QueueTriggerPubSubType::serialize(
const void* const data,
SerializedPayload_t& payload,
DataRepresentationId_t data_representation)
{
const QueueTrigger* p_type = static_cast<const QueueTrigger*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2);
payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
ser.set_encoding_flag(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR :
eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2);
try
{
// Serialize encapsulation
ser.serialize_encapsulation();
// Serialize the object.
ser << *p_type;
ser.set_dds_cdr_options({0,0});
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
// Get the serialized length
payload.length = static_cast<uint32_t>(ser.get_serialized_data_length());
return true;
}
bool QueueTriggerPubSubType::deserialize(
SerializedPayload_t& payload,
void* data)
{
try
{
// Convert DATA to pointer of your type
QueueTrigger* p_type = static_cast<QueueTrigger*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
// Object that deserializes the data.
eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN);
// Deserialize encapsulation.
deser.read_encapsulation();
payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
// Deserialize the object.
deser >> *p_type;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return false;
}
return true;
}
uint32_t QueueTriggerPubSubType::calculate_serialized_size(
const void* const data,
DataRepresentationId_t data_representation)
{
try
{
eprosima::fastcdr::CdrSizeCalculator calculator(
data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
size_t current_alignment {0};
return static_cast<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const QueueTrigger*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* QueueTriggerPubSubType::create_data()
{
return reinterpret_cast<void*>(new QueueTrigger());
}
void QueueTriggerPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<QueueTrigger*>(data));
}
bool QueueTriggerPubSubType::compute_key(
SerializedPayload_t& payload,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
QueueTrigger data;
if (deserialize(payload, static_cast<void*>(&data)))
{
return compute_key(static_cast<void*>(&data), handle, force_md5);
}
return false;
}
bool QueueTriggerPubSubType::compute_key(
const void* const data,
InstanceHandle_t& handle,
bool force_md5)
{
if (!is_compute_key_provided)
{
return false;
}
const QueueTrigger* p_type = static_cast<const QueueTrigger*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
Queue_QueueTrigger_max_key_cdr_typesize);
// Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || Queue_QueueTrigger_max_key_cdr_typesize > 16)
{
md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
md5_.finalize();
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = md5_.digest[i];
}
}
else
{
for (uint8_t i = 0; i < 16; ++i)
{
handle.value[i] = key_buffer_[i];
}
}
return true;
}
void QueueTriggerPubSubType::register_type_object_representation()
{
register_QueueTrigger_type_identifier(type_identifiers_);
}
QueueSuccessPubSubType::QueueSuccessPubSubType()
{ {
set_name("InternalSystem::IoCtrlReq"); set_name("Queue::QueueSuccess");
uint32_t type_size = InternalSystem_IoCtrlReq_max_cdr_typesize; uint32_t type_size = Queue_QueueSuccess_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/ max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false; is_compute_key_provided = false;
uint32_t key_length = InternalSystem_IoCtrlReq_max_key_cdr_typesize > 16 ? InternalSystem_IoCtrlReq_max_key_cdr_typesize : 16; uint32_t key_length = Queue_QueueSuccess_max_key_cdr_typesize > 16 ? Queue_QueueSuccess_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length)); key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length); memset(key_buffer_, 0, key_length);
} }
IoCtrlReqPubSubType::~IoCtrlReqPubSubType() QueueSuccessPubSubType::~QueueSuccessPubSubType()
{ {
if (key_buffer_ != nullptr) if (key_buffer_ != nullptr)
{ {
@ -2785,12 +3331,12 @@ namespace InternalSystem {
} }
} }
bool IoCtrlReqPubSubType::serialize( bool QueueSuccessPubSubType::serialize(
const void* const data, const void* const data,
SerializedPayload_t& payload, SerializedPayload_t& payload,
DataRepresentationId_t data_representation) DataRepresentationId_t data_representation)
{ {
const IoCtrlReq* p_type = static_cast<const IoCtrlReq*>(data); const QueueSuccess* p_type = static_cast<const QueueSuccess*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size); eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
@ -2822,14 +3368,14 @@ namespace InternalSystem {
return true; return true;
} }
bool IoCtrlReqPubSubType::deserialize( bool QueueSuccessPubSubType::deserialize(
SerializedPayload_t& payload, SerializedPayload_t& payload,
void* data) void* data)
{ {
try try
{ {
// Convert DATA to pointer of your type // Convert DATA to pointer of your type
IoCtrlReq* p_type = static_cast<IoCtrlReq*>(data); QueueSuccess* p_type = static_cast<QueueSuccess*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length); eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
@ -2852,7 +3398,7 @@ namespace InternalSystem {
return true; return true;
} }
uint32_t IoCtrlReqPubSubType::calculate_serialized_size( uint32_t QueueSuccessPubSubType::calculate_serialized_size(
const void* const data, const void* const data,
DataRepresentationId_t data_representation) DataRepresentationId_t data_representation)
{ {
@ -2863,7 +3409,7 @@ namespace InternalSystem {
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
size_t current_alignment {0}; size_t current_alignment {0};
return static_cast<uint32_t>(calculator.calculate_serialized_size( return static_cast<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const IoCtrlReq*>(data), current_alignment)) + *static_cast<const QueueSuccess*>(data), current_alignment)) +
4u /*encapsulation*/; 4u /*encapsulation*/;
} }
catch (eprosima::fastcdr::exception::Exception& /*exception*/) catch (eprosima::fastcdr::exception::Exception& /*exception*/)
@ -2872,18 +3418,18 @@ namespace InternalSystem {
} }
} }
void* IoCtrlReqPubSubType::create_data() void* QueueSuccessPubSubType::create_data()
{ {
return reinterpret_cast<void*>(new IoCtrlReq()); return reinterpret_cast<void*>(new QueueSuccess());
} }
void IoCtrlReqPubSubType::delete_data( void QueueSuccessPubSubType::delete_data(
void* data) void* data)
{ {
delete(reinterpret_cast<IoCtrlReq*>(data)); delete(reinterpret_cast<QueueSuccess*>(data));
} }
bool IoCtrlReqPubSubType::compute_key( bool QueueSuccessPubSubType::compute_key(
SerializedPayload_t& payload, SerializedPayload_t& payload,
InstanceHandle_t& handle, InstanceHandle_t& handle,
bool force_md5) bool force_md5)
@ -2893,7 +3439,7 @@ namespace InternalSystem {
return false; return false;
} }
IoCtrlReq data; QueueSuccess data;
if (deserialize(payload, static_cast<void*>(&data))) if (deserialize(payload, static_cast<void*>(&data)))
{ {
return compute_key(static_cast<void*>(&data), handle, force_md5); return compute_key(static_cast<void*>(&data), handle, force_md5);
@ -2902,7 +3448,7 @@ namespace InternalSystem {
return false; return false;
} }
bool IoCtrlReqPubSubType::compute_key( bool QueueSuccessPubSubType::compute_key(
const void* const data, const void* const data,
InstanceHandle_t& handle, InstanceHandle_t& handle,
bool force_md5) bool force_md5)
@ -2912,17 +3458,17 @@ namespace InternalSystem {
return false; return false;
} }
const IoCtrlReq* p_type = static_cast<const IoCtrlReq*>(data); const QueueSuccess* p_type = static_cast<const QueueSuccess*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_), eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
InternalSystem_IoCtrlReq_max_key_cdr_typesize); Queue_QueueSuccess_max_key_cdr_typesize);
// Object that serializes the data. // Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type); eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || InternalSystem_IoCtrlReq_max_key_cdr_typesize > 16) if (force_md5 || Queue_QueueSuccess_max_key_cdr_typesize > 16)
{ {
md5_.init(); md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length())); md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
@ -2942,24 +3488,24 @@ namespace InternalSystem {
return true; return true;
} }
void IoCtrlReqPubSubType::register_type_object_representation() void QueueSuccessPubSubType::register_type_object_representation()
{ {
register_IoCtrlReq_type_identifier(type_identifiers_); register_QueueSuccess_type_identifier(type_identifiers_);
} }
IoCtrlRspPubSubType::IoCtrlRspPubSubType() QueueFailurePubSubType::QueueFailurePubSubType()
{ {
set_name("InternalSystem::IoCtrlRsp"); set_name("Queue::QueueFailure");
uint32_t type_size = InternalSystem_IoCtrlRsp_max_cdr_typesize; uint32_t type_size = Queue_QueueFailure_max_cdr_typesize;
type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ type_size += static_cast<uint32_t>(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */
max_serialized_type_size = type_size + 4; /*encapsulation*/ max_serialized_type_size = type_size + 4; /*encapsulation*/
is_compute_key_provided = false; is_compute_key_provided = false;
uint32_t key_length = InternalSystem_IoCtrlRsp_max_key_cdr_typesize > 16 ? InternalSystem_IoCtrlRsp_max_key_cdr_typesize : 16; uint32_t key_length = Queue_QueueFailure_max_key_cdr_typesize > 16 ? Queue_QueueFailure_max_key_cdr_typesize : 16;
key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length)); key_buffer_ = reinterpret_cast<unsigned char*>(malloc(key_length));
memset(key_buffer_, 0, key_length); memset(key_buffer_, 0, key_length);
} }
IoCtrlRspPubSubType::~IoCtrlRspPubSubType() QueueFailurePubSubType::~QueueFailurePubSubType()
{ {
if (key_buffer_ != nullptr) if (key_buffer_ != nullptr)
{ {
@ -2967,12 +3513,12 @@ namespace InternalSystem {
} }
} }
bool IoCtrlRspPubSubType::serialize( bool QueueFailurePubSubType::serialize(
const void* const data, const void* const data,
SerializedPayload_t& payload, SerializedPayload_t& payload,
DataRepresentationId_t data_representation) DataRepresentationId_t data_representation)
{ {
const IoCtrlRsp* p_type = static_cast<const IoCtrlRsp*>(data); const QueueFailure* p_type = static_cast<const QueueFailure*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size); eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.max_size);
@ -3004,14 +3550,14 @@ namespace InternalSystem {
return true; return true;
} }
bool IoCtrlRspPubSubType::deserialize( bool QueueFailurePubSubType::deserialize(
SerializedPayload_t& payload, SerializedPayload_t& payload,
void* data) void* data)
{ {
try try
{ {
// Convert DATA to pointer of your type // Convert DATA to pointer of your type
IoCtrlRsp* p_type = static_cast<IoCtrlRsp*>(data); QueueFailure* p_type = static_cast<QueueFailure*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length); eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
@ -3034,7 +3580,7 @@ namespace InternalSystem {
return true; return true;
} }
uint32_t IoCtrlRspPubSubType::calculate_serialized_size( uint32_t QueueFailurePubSubType::calculate_serialized_size(
const void* const data, const void* const data,
DataRepresentationId_t data_representation) DataRepresentationId_t data_representation)
{ {
@ -3045,7 +3591,7 @@ namespace InternalSystem {
eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2);
size_t current_alignment {0}; size_t current_alignment {0};
return static_cast<uint32_t>(calculator.calculate_serialized_size( return static_cast<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const IoCtrlRsp*>(data), current_alignment)) + *static_cast<const QueueFailure*>(data), current_alignment)) +
4u /*encapsulation*/; 4u /*encapsulation*/;
} }
catch (eprosima::fastcdr::exception::Exception& /*exception*/) catch (eprosima::fastcdr::exception::Exception& /*exception*/)
@ -3054,18 +3600,18 @@ namespace InternalSystem {
} }
} }
void* IoCtrlRspPubSubType::create_data() void* QueueFailurePubSubType::create_data()
{ {
return reinterpret_cast<void*>(new IoCtrlRsp()); return reinterpret_cast<void*>(new QueueFailure());
} }
void IoCtrlRspPubSubType::delete_data( void QueueFailurePubSubType::delete_data(
void* data) void* data)
{ {
delete(reinterpret_cast<IoCtrlRsp*>(data)); delete(reinterpret_cast<QueueFailure*>(data));
} }
bool IoCtrlRspPubSubType::compute_key( bool QueueFailurePubSubType::compute_key(
SerializedPayload_t& payload, SerializedPayload_t& payload,
InstanceHandle_t& handle, InstanceHandle_t& handle,
bool force_md5) bool force_md5)
@ -3075,7 +3621,7 @@ namespace InternalSystem {
return false; return false;
} }
IoCtrlRsp data; QueueFailure data;
if (deserialize(payload, static_cast<void*>(&data))) if (deserialize(payload, static_cast<void*>(&data)))
{ {
return compute_key(static_cast<void*>(&data), handle, force_md5); return compute_key(static_cast<void*>(&data), handle, force_md5);
@ -3084,7 +3630,7 @@ namespace InternalSystem {
return false; return false;
} }
bool IoCtrlRspPubSubType::compute_key( bool QueueFailurePubSubType::compute_key(
const void* const data, const void* const data,
InstanceHandle_t& handle, InstanceHandle_t& handle,
bool force_md5) bool force_md5)
@ -3094,17 +3640,17 @@ namespace InternalSystem {
return false; return false;
} }
const IoCtrlRsp* p_type = static_cast<const IoCtrlRsp*>(data); const QueueFailure* p_type = static_cast<const QueueFailure*>(data);
// Object that manages the raw buffer. // Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_), eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(key_buffer_),
InternalSystem_IoCtrlRsp_max_key_cdr_typesize); Queue_QueueFailure_max_key_cdr_typesize);
// Object that serializes the data. // Object that serializes the data.
eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2);
ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2);
eprosima::fastcdr::serialize_key(ser, *p_type); eprosima::fastcdr::serialize_key(ser, *p_type);
if (force_md5 || InternalSystem_IoCtrlRsp_max_key_cdr_typesize > 16) if (force_md5 || Queue_QueueFailure_max_key_cdr_typesize > 16)
{ {
md5_.init(); md5_.init();
md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length())); md5_.update(key_buffer_, static_cast<unsigned int>(ser.get_serialized_data_length()));
@ -3124,13 +3670,13 @@ namespace InternalSystem {
return true; return true;
} }
void IoCtrlRspPubSubType::register_type_object_representation() void QueueFailurePubSubType::register_type_object_representation()
{ {
register_IoCtrlRsp_type_identifier(type_identifiers_); register_QueueFailure_type_identifier(type_identifiers_);
} }
} // namespace InternalSystem } // namespace Queue
// Include auxiliary functions like for serializing/deserializing. // Include auxiliary functions like for serializing/deserializing.
#include "SystemCdrAux.ipp" #include "WeighingDDSTypeCdrAux.ipp"

@ -13,15 +13,15 @@
// limitations under the License. // limitations under the License.
/*! /*!
* @file SystemPubSubTypes.hpp * @file WeighingDDSTypePubSubTypes.hpp
* This header file contains the declaration of the serialization functions. * This header file contains the declaration of the serialization functions.
* *
* This file was generated by the tool fastddsgen. * This file was generated by the tool fastddsgen.
*/ */
#ifndef FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_PUBSUBTYPES_HPP #ifndef FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_PUBSUBTYPES_HPP
#define FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_PUBSUBTYPES_HPP #define FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_PUBSUBTYPES_HPP
#include <fastdds/dds/core/policy/QosPolicies.hpp> #include <fastdds/dds/core/policy/QosPolicies.hpp>
#include <fastdds/dds/topic/TopicDataType.hpp> #include <fastdds/dds/topic/TopicDataType.hpp>
@ -29,12 +29,12 @@
#include <fastdds/rtps/common/SerializedPayload.hpp> #include <fastdds/rtps/common/SerializedPayload.hpp>
#include <fastdds/utils/md5.hpp> #include <fastdds/utils/md5.hpp>
#include "System.hpp" #include "WeighingDDSType.hpp"
#if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3) #if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3)
#error \ #error \
Generated System is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. Generated WeighingDDSType is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen.
#endif // FASTDDS_GEN_API_VER #endif // FASTDDS_GEN_API_VER
namespace WeighingSystem namespace WeighingSystem
@ -42,7 +42,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type ScaleInfo defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type ScaleInfo defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class ScaleInfoPubSubType : public eprosima::fastdds::dds::TopicDataType class ScaleInfoPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -123,7 +123,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type ScaleCommand defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type ScaleCommand defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class ScaleCommandPubSubType : public eprosima::fastdds::dds::TopicDataType class ScaleCommandPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -204,7 +204,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type WeightInfoOk defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type WeightInfoOk defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class WeightInfoOkPubSubType : public eprosima::fastdds::dds::TopicDataType class WeightInfoOkPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -285,7 +285,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type WeightInfoError defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type WeightInfoError defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class WeightInfoErrorPubSubType : public eprosima::fastdds::dds::TopicDataType class WeightInfoErrorPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -366,7 +366,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type BarCommandUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type BarCommandUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class BarCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class BarCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -447,7 +447,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type LightsCommandUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type LightsCommandUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class LightsCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class LightsCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -528,7 +528,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type InfraredCommandUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type InfraredCommandUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class InfraredCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class InfraredCommandUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -609,7 +609,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type BarUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type BarUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class BarUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class BarUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -690,7 +690,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type LightsUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type LightsUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class LightsUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class LightsUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -771,7 +771,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type InfraredUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type InfraredUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class InfraredUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class InfraredUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -852,7 +852,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type LicenseSnapUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type LicenseSnapUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class LicenseSnapUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class LicenseSnapUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -933,7 +933,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type Voice defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type Voice defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class VoicePubSubType : public eprosima::fastdds::dds::TopicDataType class VoicePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -1014,7 +1014,7 @@ namespace WeighingSystem
/*! /*!
* @brief This class represents the TopicDataType of the type SummaryUpdate defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type SummaryUpdate defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class SummaryUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType class SummaryUpdatePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -1092,13 +1092,172 @@ namespace WeighingSystem
unsigned char* key_buffer_; unsigned char* key_buffer_;
}; };
} // namespace WeighingSystem
namespace InternalSystem /*!
* @brief This class represents the TopicDataType of the type ReadCardReq defined by the user in the IDL file.
* @ingroup WeighingDDSType
*/
class ReadCardReqPubSubType : public eprosima::fastdds::dds::TopicDataType
{
public:
typedef ReadCardReq type;
eProsima_user_DllExport ReadCardReqPubSubType();
eProsima_user_DllExport ~ReadCardReqPubSubType() override;
eProsima_user_DllExport bool serialize(
const void* const data,
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool deserialize(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
void* data) override;
eProsima_user_DllExport uint32_t calculate_serialized_size(
const void* const data,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool compute_key(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport bool compute_key(
const void* const data,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport void* create_data() override;
eProsima_user_DllExport void delete_data(
void* data) override;
//Register TypeObject representation in Fast DDS TypeObjectRegistry
eProsima_user_DllExport void register_type_object_representation() override;
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
eProsima_user_DllExport inline bool is_bounded() const override
{
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
eProsima_user_DllExport inline bool is_plain(
eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override
{
static_cast<void>(data_representation);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
eProsima_user_DllExport inline bool construct_sample(
void* memory) const override
{ {
static_cast<void>(memory);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
private:
eprosima::fastdds::MD5 md5_;
unsigned char* key_buffer_;
};
/*!
* @brief This class represents the TopicDataType of the type ReadCardRsp defined by the user in the IDL file.
* @ingroup WeighingDDSType
*/
class ReadCardRspPubSubType : public eprosima::fastdds::dds::TopicDataType
{
public:
typedef ReadCardRsp type;
eProsima_user_DllExport ReadCardRspPubSubType();
eProsima_user_DllExport ~ReadCardRspPubSubType() override;
eProsima_user_DllExport bool serialize(
const void* const data,
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool deserialize(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
void* data) override;
eProsima_user_DllExport uint32_t calculate_serialized_size(
const void* const data,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool compute_key(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport bool compute_key(
const void* const data,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport void* create_data() override;
eProsima_user_DllExport void delete_data(
void* data) override;
//Register TypeObject representation in Fast DDS TypeObjectRegistry
eProsima_user_DllExport void register_type_object_representation() override;
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
eProsima_user_DllExport inline bool is_bounded() const override
{
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
eProsima_user_DllExport inline bool is_plain(
eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override
{
static_cast<void>(data_representation);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
eProsima_user_DllExport inline bool construct_sample(
void* memory) const override
{
static_cast<void>(memory);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
private:
eprosima::fastdds::MD5 md5_;
unsigned char* key_buffer_;
};
/*! /*!
* @brief This class represents the TopicDataType of the type PrintReq defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type PrintReq defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class PrintReqPubSubType : public eprosima::fastdds::dds::TopicDataType class PrintReqPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -1179,7 +1338,7 @@ namespace InternalSystem
/*! /*!
* @brief This class represents the TopicDataType of the type PrintRsp defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type PrintRsp defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class PrintRspPubSubType : public eprosima::fastdds::dds::TopicDataType class PrintRspPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
@ -1257,20 +1416,104 @@ namespace InternalSystem
unsigned char* key_buffer_; unsigned char* key_buffer_;
}; };
} // namespace WeighingSystem
namespace Queue
{
/*!
* @brief This class represents the TopicDataType of the type QueueTrigger defined by the user in the IDL file.
* @ingroup WeighingDDSType
*/
class QueueTriggerPubSubType : public eprosima::fastdds::dds::TopicDataType
{
public:
typedef QueueTrigger type;
eProsima_user_DllExport QueueTriggerPubSubType();
eProsima_user_DllExport ~QueueTriggerPubSubType() override;
eProsima_user_DllExport bool serialize(
const void* const data,
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool deserialize(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
void* data) override;
eProsima_user_DllExport uint32_t calculate_serialized_size(
const void* const data,
eprosima::fastdds::dds::DataRepresentationId_t data_representation) override;
eProsima_user_DllExport bool compute_key(
eprosima::fastdds::rtps::SerializedPayload_t& payload,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport bool compute_key(
const void* const data,
eprosima::fastdds::rtps::InstanceHandle_t& ihandle,
bool force_md5 = false) override;
eProsima_user_DllExport void* create_data() override;
eProsima_user_DllExport void delete_data(
void* data) override;
//Register TypeObject representation in Fast DDS TypeObjectRegistry
eProsima_user_DllExport void register_type_object_representation() override;
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
eProsima_user_DllExport inline bool is_bounded() const override
{
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED
#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
eProsima_user_DllExport inline bool is_plain(
eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override
{
static_cast<void>(data_representation);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN
#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
eProsima_user_DllExport inline bool construct_sample(
void* memory) const override
{
static_cast<void>(memory);
return false;
}
#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE
private:
eprosima::fastdds::MD5 md5_;
unsigned char* key_buffer_;
};
/*! /*!
* @brief This class represents the TopicDataType of the type IoCtrlReq defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type QueueSuccess defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class IoCtrlReqPubSubType : public eprosima::fastdds::dds::TopicDataType class QueueSuccessPubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
public: public:
typedef IoCtrlReq type; typedef QueueSuccess type;
eProsima_user_DllExport IoCtrlReqPubSubType(); eProsima_user_DllExport QueueSuccessPubSubType();
eProsima_user_DllExport ~IoCtrlReqPubSubType() override; eProsima_user_DllExport ~QueueSuccessPubSubType() override;
eProsima_user_DllExport bool serialize( eProsima_user_DllExport bool serialize(
const void* const data, const void* const data,
@ -1340,18 +1583,18 @@ namespace InternalSystem
}; };
/*! /*!
* @brief This class represents the TopicDataType of the type IoCtrlRsp defined by the user in the IDL file. * @brief This class represents the TopicDataType of the type QueueFailure defined by the user in the IDL file.
* @ingroup System * @ingroup WeighingDDSType
*/ */
class IoCtrlRspPubSubType : public eprosima::fastdds::dds::TopicDataType class QueueFailurePubSubType : public eprosima::fastdds::dds::TopicDataType
{ {
public: public:
typedef IoCtrlRsp type; typedef QueueFailure type;
eProsima_user_DllExport IoCtrlRspPubSubType(); eProsima_user_DllExport QueueFailurePubSubType();
eProsima_user_DllExport ~IoCtrlRspPubSubType() override; eProsima_user_DllExport ~QueueFailurePubSubType() override;
eProsima_user_DllExport bool serialize( eProsima_user_DllExport bool serialize(
const void* const data, const void* const data,
@ -1419,7 +1662,7 @@ namespace InternalSystem
unsigned char* key_buffer_; unsigned char* key_buffer_;
}; };
} // namespace InternalSystem } // namespace Queue
#endif // FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_PUBSUBTYPES_HPP #endif // FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_PUBSUBTYPES_HPP

File diff suppressed because it is too large Load Diff

@ -13,14 +13,14 @@
// limitations under the License. // limitations under the License.
/*! /*!
* @file SystemTypeObjectSupport.hpp * @file WeighingDDSTypeTypeObjectSupport.hpp
* Header file containing the API required to register the TypeObject representation of the described types in the IDL file * Header file containing the API required to register the TypeObject representation of the described types in the IDL file
* *
* This file was generated by the tool fastddsgen. * This file was generated by the tool fastddsgen.
*/ */
#ifndef FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_TYPE_OBJECT_SUPPORT_HPP #ifndef FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_TYPE_OBJECT_SUPPORT_HPP
#define FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_TYPE_OBJECT_SUPPORT_HPP #define FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_TYPE_OBJECT_SUPPORT_HPP
#include <fastdds/dds/xtypes/type_representation/TypeObject.hpp> #include <fastdds/dds/xtypes/type_representation/TypeObject.hpp>
@ -207,8 +207,32 @@ eProsima_user_DllExport void register_Voice_type_identifier(
eProsima_user_DllExport void register_SummaryUpdate_type_identifier( eProsima_user_DllExport void register_SummaryUpdate_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
} // namespace WeighingSystem /**
namespace InternalSystem { * @brief Register ReadCardReq related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered.
* Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is
* indirectly registered as well.
*
* @param[out] TypeIdentifier of the registered type.
* The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers.
* Invalid TypeIdentifier is returned in case of error.
*/
eProsima_user_DllExport void register_ReadCardReq_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
/**
* @brief Register ReadCardRsp related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered.
* Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is
* indirectly registered as well.
*
* @param[out] TypeIdentifier of the registered type.
* The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers.
* Invalid TypeIdentifier is returned in case of error.
*/
eProsima_user_DllExport void register_ReadCardRsp_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
/** /**
* @brief Register PrintReq related TypeIdentifier. * @brief Register PrintReq related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered. * Fully-descriptive TypeIdentifiers are directly registered.
@ -235,8 +259,23 @@ eProsima_user_DllExport void register_PrintReq_type_identifier(
eProsima_user_DllExport void register_PrintRsp_type_identifier( eProsima_user_DllExport void register_PrintRsp_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
} // namespace WeighingSystem
namespace Queue {
/**
* @brief Register QueueTrigger related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered.
* Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is
* indirectly registered as well.
*
* @param[out] TypeIdentifier of the registered type.
* The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers.
* Invalid TypeIdentifier is returned in case of error.
*/
eProsima_user_DllExport void register_QueueTrigger_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
/** /**
* @brief Register IoCtrlReq related TypeIdentifier. * @brief Register QueueSuccess related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered. * Fully-descriptive TypeIdentifiers are directly registered.
* Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is
* indirectly registered as well. * indirectly registered as well.
@ -245,11 +284,11 @@ eProsima_user_DllExport void register_PrintRsp_type_identifier(
* The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers.
* Invalid TypeIdentifier is returned in case of error. * Invalid TypeIdentifier is returned in case of error.
*/ */
eProsima_user_DllExport void register_IoCtrlReq_type_identifier( eProsima_user_DllExport void register_QueueSuccess_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
/** /**
* @brief Register IoCtrlRsp related TypeIdentifier. * @brief Register QueueFailure related TypeIdentifier.
* Fully-descriptive TypeIdentifiers are directly registered. * Fully-descriptive TypeIdentifiers are directly registered.
* Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is
* indirectly registered as well. * indirectly registered as well.
@ -258,12 +297,12 @@ eProsima_user_DllExport void register_IoCtrlReq_type_identifier(
* The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers.
* Invalid TypeIdentifier is returned in case of error. * Invalid TypeIdentifier is returned in case of error.
*/ */
eProsima_user_DllExport void register_IoCtrlRsp_type_identifier( eProsima_user_DllExport void register_QueueFailure_type_identifier(
eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids);
} // namespace InternalSystem } // namespace Queue
#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC #endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
#endif // FAST_DDS_GENERATED__INTERNALSYSTEM_SYSTEM_TYPE_OBJECT_SUPPORT_HPP #endif // FAST_DDS_GENERATED__QUEUE_WEIGHINGDDSTYPE_TYPE_OBJECT_SUPPORT_HPP

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -449,7 +449,7 @@ void PublisherApp::run(std::shared_ptr<mqtt::async_client> dev)
{ {
print_msg.clear(); print_msg.clear();
print_msg["Title"] = "五彩湾"; print_msg["Title"] = "贵州渝黔锰业有限公司提货单";
print_msg["GrossDeviceID"] = std::to_string(info.GrossDeviceID()); print_msg["GrossDeviceID"] = std::to_string(info.GrossDeviceID());
print_msg["GrossDeviceName"] = info.GrossDeviceName(); print_msg["GrossDeviceName"] = info.GrossDeviceName();
print_msg["TareDeviceID"] = std::to_string(info.TareDeviceID()); print_msg["TareDeviceID"] = std::to_string(info.TareDeviceID());

@ -0,0 +1,144 @@
diff --git a/core/Publisher.cxx b/core/Publisher.cxx
index 6aba885..73e627f 100644
--- a/core/Publisher.cxx
+++ b/core/Publisher.cxx
@@ -333,12 +333,21 @@ bool PublisherApp::print_receipt(const std::map<std::string, std::string>& msg)
return true;
}
+#define WEIGH_IDLE 0
+#define WEIGH_LIC 1
+#define WEIGH_STABLE1 2
+#define WEIGH_STABLE2 3
+#define WEIGH_PRINT 4
+#define WEIGH_ERROR 5
+#define WEIGH_LEAVE 6
+
void PublisherApp::run()
{
- uint8_t send_sum = 0;
- uint8_t is_print = 0;
std::string license_no = "";
float stable_weight = 0;
+ float stable_weight1 = 0;
+ float stable_weight2 = 0;
+ int weigh_state = WEIGH_IDLE;
while (!is_stopped())
{
@@ -357,6 +366,7 @@ void PublisherApp::run()
if (license_no == "")
{
license_no = info.License();
+ weigh_state = WEIGH_LIC;
}
}
else if (!DdsMsgData::ScaleInfo_queue_.empty())
@@ -378,19 +388,18 @@ void PublisherApp::run()
else
{
stable_weight = 0;
- send_sum = 0;
}
if (info.HasVehicle() == 0)
{
license_no = "";
- if (is_print == 1)
+ if (weigh_state == WEIGH_LEAVE)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "down";
bar_ctrl(ctrl);
- is_print = 0;
+ weigh_state = WEIGH_IDLE;
}
}
}
@@ -464,7 +473,7 @@ void PublisherApp::run()
print_receipt(print_msg);
- is_print = 1;
+ weigh_state = WEIGH_LEAVE;
std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "up";
bar_ctrl(ctrl);
@@ -477,7 +486,7 @@ void PublisherApp::run()
dds_lock.unlock();
std::this_thread::sleep_for(std::chrono::seconds(3));
- send_sum = 0;
+ weigh_state = WEIGH_ERROR;
}
else
{
@@ -486,17 +495,57 @@ void PublisherApp::run()
}
// logic
- if (send_sum == 0)
+ switch (weigh_state)
{
- if ((stable_weight != 0) && (license_no != ""))
- {
- DEBUG("send summary");
- WeighingSystem::SummaryUpdate info;
- info.License() = license_no;
- info.StableValue() = stable_weight;
- summary_writer_->write(&info);
- send_sum = 1;
- }
+ case WEIGH_IDLE:
+ break;
+ case WEIGH_LIC:
+ if ((stable_weight != 0) && (license_no != ""))
+ {
+ DEBUG("stable_weight1 " << stable_weight);
+ DEBUG("license_no " << license_no);
+ stable_weight1 = stable_weight;
+ weigh_state = WEIGH_STABLE1;
+ }
+ break;
+ case WEIGH_STABLE1:
+ if (stable_weight == 0)
+ {
+ DEBUG("weigh1 clear");
+ weigh_state = WEIGH_STABLE2;
+ }
+ break;
+ case WEIGH_STABLE2:
+ if ((stable_weight != 0) && (license_no != ""))
+ {
+ DEBUG("license_no " << license_no);
+ DEBUG("stable_weight2 " << stable_weight);
+ if (stable_weight < stable_weight1)
+ {
+ DEBUG("send sunnmary");
+ WeighingSystem::SummaryUpdate info;
+ info.License() = license_no;
+ info.StableValue() = stable_weight;
+ summary_writer_->write(&info);
+ weigh_state = WEIGH_PRINT;
+ }
+ else
+ {
+ weigh_state = WEIGH_IDLE;
+ }
+ }
+ break;
+ case WEIGH_PRINT:
+ break;
+ case WEIGH_ERROR:
+ std::this_thread::sleep_for(std::chrono::seconds(3));
+ weigh_state = WEIGH_STABLE2;
+ break;
+ case WEIGH_LEAVE:
+ break;
+ default:
+ weigh_state = WEIGH_IDLE;
+ break;
}
// Wait for period or stop event

@ -0,0 +1,128 @@
diff --git a/core/Publisher.cxx b/core/Publisher.cxx
index 6aba885..acf2b7c 100644
--- a/core/Publisher.cxx
+++ b/core/Publisher.cxx
@@ -333,12 +333,19 @@ bool PublisherApp::print_receipt(const std::map<std::string, std::string>& msg)
return true;
}
+#define WEIGH_IDLE 0
+#define WEIGH_LIC 1
+#define WEIGH_STABLE 2
+#define WEIGH_PRINT 3
+#define WEIGH_ERROR 4
+#define WEIGH_LEAVE 5
+
void PublisherApp::run()
{
- uint8_t send_sum = 0;
- uint8_t is_print = 0;
std::string license_no = "";
float stable_weight = 0;
+ int weigh_state = WEIGH_IDLE;
+ uint16_t weigh_timer = 0;
while (!is_stopped())
{
@@ -357,6 +364,7 @@ void PublisherApp::run()
if (license_no == "")
{
license_no = info.License();
+ weigh_state = WEIGH_LIC;
}
}
else if (!DdsMsgData::ScaleInfo_queue_.empty())
@@ -378,19 +386,18 @@ void PublisherApp::run()
else
{
stable_weight = 0;
- send_sum = 0;
}
if (info.HasVehicle() == 0)
{
license_no = "";
- if (is_print == 1)
+ if (weigh_state == WEIGH_LEAVE)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "down";
bar_ctrl(ctrl);
- is_print = 0;
+ weigh_state = WEIGH_IDLE;
}
}
}
@@ -464,7 +471,7 @@ void PublisherApp::run()
print_receipt(print_msg);
- is_print = 1;
+ weigh_state = WEIGH_LEAVE;
std::map<std::string, std::string> ctrl;
ctrl["FrontBar"] = "up";
bar_ctrl(ctrl);
@@ -477,7 +484,7 @@ void PublisherApp::run()
dds_lock.unlock();
std::this_thread::sleep_for(std::chrono::seconds(3));
- send_sum = 0;
+ weigh_state = WEIGH_ERROR;
}
else
{
@@ -486,17 +493,43 @@ void PublisherApp::run()
}
// logic
- if (send_sum == 0)
+ switch (weigh_state)
{
- if ((stable_weight != 0) && (license_no != ""))
- {
- DEBUG("send summary");
- WeighingSystem::SummaryUpdate info;
- info.License() = license_no;
- info.StableValue() = stable_weight;
- summary_writer_->write(&info);
- send_sum = 1;
- }
+ case WEIGH_IDLE:
+ weigh_timer = 0;
+ break;
+ case WEIGH_LIC:
+ if (weigh_timer++ > 600)
+ {
+ DEBUG("timer reach");
+ DEBUG("license_no " << license_no);
+ DEBUG("stable_weight " << stable_weight);
+ weigh_state = WEIGH_STABLE;
+ weigh_timer = 0;
+ }
+ break;
+ case WEIGH_STABLE:
+ if ((stable_weight != 0) && (license_no != ""))
+ {
+ DEBUG("send summary");
+ WeighingSystem::SummaryUpdate info;
+ info.License() = license_no;
+ info.StableValue() = stable_weight;
+ summary_writer_->write(&info);
+ weigh_state = WEIGH_PRINT;
+ }
+ break;
+ case WEIGH_PRINT:
+ break;
+ case WEIGH_ERROR:
+ std::this_thread::sleep_for(std::chrono::seconds(3));
+ weigh_state = WEIGH_STABLE;
+ break;
+ case WEIGH_LEAVE:
+ break;
+ default:
+ weigh_state = WEIGH_IDLE;
+ break;
}
// Wait for period or stop event

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
#ifndef _MSGHANDLER_HPP_ #ifndef _MSGHANDLER2_HPP_
#define _MSGHANDLER_HPP_ #define _MSGHANDLER2_HPP_
#include <queue> #include <queue>
#include <mutex> #include <mutex>
@ -44,13 +44,22 @@ private:
void Page_Cut(std::vector<uint8_t>& Data); void Page_Cut(std::vector<uint8_t>& Data);
void Page_End(std::vector<uint8_t>& Data); void Page_End(std::vector<uint8_t>& Data);
void GtstrLength(int iVal, char *p); void GtstrLength(int iVal, char *p);
bool is_chinese_char(const std::string& str, size_t start_byte);
int get_utf8_char_width(const std::string& str, size_t start_byte);
size_t get_utf8_display_width(const std::string& str);
std::vector<std::string> split_utf8_by_width(const std::string& str, size_t max_width);
bool check_odd(const std::string date);
void Print1_1(const std::map<std::string, std::string>& msg); void Print1_1(const std::map<std::string, std::string>& msg);
void Print1_2(const std::map<std::string, std::string>& msg);
void Print2_2(const std::map<std::string, std::string>& msg);
void Print3_2(const std::map<std::string, std::string>& msg);
void Print4_2(const std::map<std::string, std::string>& msg);
void Print5_2(const std::map<std::string, std::string>& msg);
void Print6_2(const std::map<std::string, std::string>& msg);
void Print1_3(const std::map<std::string, std::string>& msg);
void Print2_3(const std::map<std::string, std::string>& msg);
void Print4_3(const std::map<std::string, std::string>& msg);
void Print5_3(const std::map<std::string, std::string>& msg);
void Print6_3(const std::map<std::string, std::string>& msg);
void Print8_3(const std::map<std::string, std::string>& msg);
}; };
#endif #endif

@ -33,7 +33,7 @@
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp> #include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp> #include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "MsgHandler.hpp" #include "MsgHandler.hpp"
@ -48,7 +48,7 @@ PublisherApp::PublisherApp(
, publisher_(nullptr) , publisher_(nullptr)
, topic_(nullptr) , topic_(nullptr)
, writer_(nullptr) , writer_(nullptr)
, type_(new InternalSystem::PrintRspPubSubType()) , type_(new WeighingSystem::PrintRspPubSubType())
, matched_(0) , matched_(0)
, samples_sent_(0) , samples_sent_(0)
, stop_(false) , stop_(false)
@ -82,7 +82,7 @@ PublisherApp::PublisherApp(
// Create the topic // Create the topic
TopicQos topic_qos = TOPIC_QOS_DEFAULT; TopicQos topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos); participant_->get_default_topic_qos(topic_qos);
topic_ = participant_->create_topic("PrintRspTopic", type_.get_type_name(), topic_qos); topic_ = participant_->create_topic("PrintRsp", type_.get_type_name(), topic_qos);
if (topic_ == nullptr) if (topic_ == nullptr)
{ {
throw std::runtime_error("InternalSystem::PrintRsp Topic initialization failed"); throw std::runtime_error("InternalSystem::PrintRsp Topic initialization failed");
@ -149,7 +149,7 @@ void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
{ {
if(!MsgData::PrintReq_queue_.empty()) if(!MsgData::PrintReq_queue_.empty())
{ {
InternalSystem::PrintReq req = std::move(MsgData::PrintReq_queue_.front()); WeighingSystem::PrintReq req = std::move(MsgData::PrintReq_queue_.front());
MsgData::PrintReq_queue_.pop(); MsgData::PrintReq_queue_.pop();
lock.unlock(); lock.unlock();
@ -189,7 +189,7 @@ bool PublisherApp::publish()
if (!is_stopped()) if (!is_stopped())
{ {
/* Initialize your structure here */ /* Initialize your structure here */
InternalSystem::PrintReq sample_; WeighingSystem::PrintReq sample_;
ret = (RETCODE_OK == writer_->write(&sample_)); ret = (RETCODE_OK == writer_->write(&sample_));
} }
return ret; return ret;

@ -32,7 +32,7 @@
#include <fastdds/dds/subscriber/SampleInfo.hpp> #include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp> #include <fastdds/dds/subscriber/Subscriber.hpp>
#include "SystemPubSubTypes.hpp" #include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp" #include "msg.hpp"
#include "DEBUG.hpp" #include "DEBUG.hpp"
@ -46,7 +46,7 @@ SubscriberApp::SubscriberApp(
, subscriber_(nullptr) , subscriber_(nullptr)
, topic_(nullptr) , topic_(nullptr)
, reader_(nullptr) , reader_(nullptr)
, type_(new InternalSystem::PrintReqPubSubType()) , type_(new WeighingSystem::PrintReqPubSubType())
, samples_received_(0) , samples_received_(0)
, stop_(false) , stop_(false)
{ {
@ -133,9 +133,12 @@ void SubscriberApp::on_data_available(
std::string topic_name = reader->get_topicdescription()->get_name(); std::string topic_name = reader->get_topicdescription()->get_name();
DEBUG(topic_name << " Topic receviced."); DEBUG(topic_name << " Topic receviced.");
// 在第136行之前添加
std::cout << "[Print] DEBUG: topic_name from DDS = [" << topic_name << "]" << std::endl;
std::cout << "[Print] DEBUG: topic_name == PrintReq ? " << (topic_name == "PrintReq" ? "YES" : "NO") << std::endl;
if (topic_name == "PrintReq") if (topic_name == "PrintReq")
{ {
InternalSystem::PrintReq sample_; WeighingSystem::PrintReq sample_;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info))) while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{ {
if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data)
@ -143,10 +146,15 @@ void SubscriberApp::on_data_available(
{ {
std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_); std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_);
MsgData::PrintReq_queue_.push(std::move(sample_)); MsgData::PrintReq_queue_.push(std::move(sample_));
std::cout << "[Print] DEBUG: PUSHING to PrintReq_queue_ (queue size before: " << MsgData::PrintReq_queue_.size() << ")" << std::endl;
std::cout << "[Print] DEBUG: Publisher polling queue, empty() = " << MsgData::PrintReq_queue_.empty() << std::endl;
lock.unlock(); lock.unlock();
} }
} }
} }
std::cout << "[Print] DEBUG: HandleDdsMsg called successfully" << std::endl;
} }
} }

@ -29,7 +29,7 @@
#include <fastdds/dds/subscriber/DataReaderListener.hpp> #include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp> #include <fastdds/dds/topic/TypeSupport.hpp>
#include "System.hpp" #include "WeighingDDSType.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{ {

@ -63,7 +63,7 @@ std::string parse_signal(
} }
} }
std::queue<InternalSystem::PrintReq> MsgData::PrintReq_queue_; std::queue<WeighingSystem::PrintReq> MsgData::PrintReq_queue_;
std::mutex MsgData::queue_cv_mtx_; std::mutex MsgData::queue_cv_mtx_;
int main(int argc, char** argv) int main(int argc, char** argv)

@ -3,11 +3,11 @@
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#include "System.hpp" #include "WeighingDDSType.hpp"
class MsgData { class MsgData {
public: public:
static std::queue<InternalSystem::PrintReq> PrintReq_queue_; static std::queue<WeighingSystem::PrintReq> PrintReq_queue_;
static std::mutex queue_cv_mtx_; static std::mutex queue_cv_mtx_;
}; };

File diff suppressed because it is too large Load Diff

@ -0,0 +1,252 @@
#ifndef _MSGHANDLER_HPP_
#define _MSGHANDLER_HPP_
#include <chrono>
#include <cstdint>
#include <queue>
#include <mutex>
#include <vector>
#include <map>
#include <mutex>
#include <functional>
#include "WeighingDDSType.hpp"
#include <termios.h>
#define BEEP_CARD 1
#define FIND_CARD 2 // 发送命令号
#define FIND_CARD_RSP 0x08 // FindCard 响应命令号固件返回0x08
#define SET_PWD 3
#define READ_CARD 4
#define WRITE_CARD 5
#define STOP_CARD 8 // 发送/响应命令号Pause
enum class CardState {
AUTO_FIND, // 自动寻卡状态
WAIT_DDS_READ, // 等待 DDS read 命令
WAIT_DDS_WRITE, // 等待 DDS write 命令
WAIT_DDS_DECISION, // 读卡完成,等待 DDS 决定write / stop / ack
WAIT_DDS_WRITE_NEXT // 写卡成功,等待下一个 write 命令10秒超时
};
enum class PendingCommand : uint8_t { None, Find, SetPassword, ReadBlock, WriteBlock, Stop, Beep };
class MsgHandler {
public:
int fd;
std::string device;
std::map<uint8_t, std::vector<uint8_t>> m_PassWord;
MsgHandler();
~MsgHandler() = default;
void HandleDdsMsg(const std::map<std::string, std::vector<uint8_t>>& msg, unsigned long index);
int HandleDeviceMsg(WeighingSystem::ReadCardRsp& rsp);
bool SetDevice(const std::string& device);
bool InitSequence(void);
void AutoFindTick(void);
void StorePasswd(std::map<uint8_t, std::vector<uint8_t>>& data);
void SetPasswd(const std::vector<uint8_t>& data);
void FindCard(void);
void ReadCard(const std::vector<uint8_t>& data);
void WriteCard(const std::vector<uint8_t>& data);
void StopCard(void);
void BeepCard(const std::vector<uint8_t>& data);
void ResetCard(void);
int ParseDeviceMsg(std::vector<uint8_t>& data, WeighingSystem::ReadCardRsp& rsp);
bool WaitForResponse(uint8_t expected_cmd, int timeout_ms = 3000);
virtual bool OpenPort(const std::string& port, const std::string& baudrate);
virtual int SendDeviceMsg(const std::vector<uint8_t>& data);
virtual int RecvDeviceMsg(std::vector<uint8_t>& data, int timeoutMs);
int SendMsg(const std::vector<uint8_t>& data);
int RecvMsg(std::vector<uint8_t>& data, int timeoutMs);
bool isOpen() const {
return fd != -1;
}
void ClosePort();
// 【新增】内部版本,不加锁,供 ParseDeviceMsg 的 drain 循环使用
int RecvMsgInternal(std::vector<uint8_t>& data, int timeoutMs);
void SetCardState(CardState state);
unsigned long GetCurrentIndex() const;
bool IsTimeoutRecovery() const;
uint64_t GetOperationSequence() const;
bool IsReadResponseReady() const;
bool IsWriteResponseReady() const;
void ClearReadBuffer();
void SetReadResult(uint8_t resultCode, const std::string& cardId, uint8_t blockCount,
const std::vector<std::pair<uint8_t, std::vector<uint8_t>>>& blockData);
void SetWriteResult(uint8_t resultCode, const std::string& cardId, uint8_t blockNum);
int CheckDdsTimeout();
void ResetWriteTimeout();
std::function<void(const std::string& cardId)> OnCardDetected;
// 【新增】由业务层填充HandleDeviceMsg 检测到卡后写入,主循环读取并发送 QueueTrigger
std::string pending_trigger_card_;
std::mutex trigger_mtx_;
// ========== 单块操作超时控制 ==========
int GetBlockOpElapsed() const;
static constexpr int BLOCK_OPERATION_TIMEOUT_MS = 3000;
static constexpr bool VERIFY_DEVICE_CRC = true;
// 通信帧不完整或 CRC/数据校验失败时,同一读块允许额外重发的次数。
static constexpr uint8_t READ_BLOCK_MAX_RETRIES = 1;
static constexpr int READ_BLOCK_RETRY_DELAY_MS = 100;
uint8_t GetCurrentOperatingBlock() const;
bool IsBlockOperationPending() const;
void SkipCurrentBlock();
bool HasPendingReadResponse() const;
std::vector<uint8_t> GetPendingReadResponse();
CardState GetCardState() const;
// 【新增】业务层主动取消等待、立即回到自动寻卡
void ForceResetToAutoFind();
// 【新增】业务层暂停自动寻卡state 切到 AUTO_FINDm_AutoFind=false
// 用于刚发完 QueueTrigger 后的 3 秒等待期:阻止 HandleDdsMsg 接收 read/write。
void PauseAutoFind();
// 【新增】标记:是否正在执行超时恢复序列
// 原因SkipCurrentBlock 发的恢复命令可能和 HandleDdsMsg 的新命令冲突
bool m_IsInTimeoutRecovery = false;
// 【新增】重置串口并重新初始化 RC522用于块操作超时后的恢复
bool ResetSerialAndReinit();
// 【新增】刷新串口配置(供 SkipCurrentBlock 使用)
bool refreshPort();
// 【新增】保存串口参数,供 ResetSerialAndReinit 使用
std::string m_Port; // 端口名,如 "ttyS1"
speed_t m_Baudrate; // 波特率speed_t 类型)
private:
bool TryExtractDeviceFrame(std::vector<uint8_t>& data);
bool IsValidDeviceFrame(const std::vector<uint8_t>& data);
bool RetryCurrentReadBlock(const char* reason);
bool HasActiveDeviceOperation() const;
int HandleFindResponse(const std::vector<uint8_t>& data,
WeighingSystem::ReadCardRsp& rsp);
static bool IsDataBlock(uint8_t block);
bool m_AutoFind = false;
int m_FindIntervalMs = 500;
std::chrono::steady_clock::time_point m_LastFindTime;
std::string m_PreCard;
// 【新增】保存 WaitForResponse 接收到的 ReadCard 响应数据
std::vector<uint8_t> m_LastReadCardRsp;
//std::mutex mtx_; // 添加这行 - 保护串口访问
mutable std::recursive_mutex mtx_;
std::vector<uint8_t> m_ReceiveBuffer;
CardState m_CardState; // 当前状态
unsigned long m_CurrentIndex; // 保存收到的 index
std::chrono::steady_clock::time_point m_StateEnterTime; // 状态进入时间
static constexpr int DDS_TIMEOUT_MS = 20000; // DDS 命令 10 秒超时
static constexpr int DDS_DECISION_TIMEOUT_MS = 20000; // WAIT_DDS_DECISION 超时
static constexpr int DDS_WRITE_TIMEOUT_MS = 10000; // 写卡序列 10 秒超时
static constexpr int CARD_READY_IDLE_TIMEOUT_MS = 20000; // 卡就绪无任务后恢复寻卡
static constexpr int WRITE_BLOCK_OPERATION_TIMEOUT_MS = 2000;
// 读卡结果缓存
uint8_t m_ResultCode; // 结果码
std::string m_CardId; // 当前操作的卡号
uint8_t m_BlockCount; // 当前读取的块数量
std::vector<std::pair<uint8_t, std::vector<uint8_t>>> m_BlockData; // 块数据
std::vector<uint8_t> m_RequestedBlocks; // 【新增】请求的块号列表
uint8_t m_CurrentReadIndex = 0; // 【新增】当前正在读取的块索引
std::chrono::steady_clock::time_point m_ReadStartTime;
std::chrono::steady_clock::time_point m_ReadEndTime;
// 写卡请求的 pending 信息(响应时用)
uint8_t m_PendingWriteBlock = 0;
std::vector<uint8_t> m_PendingWriteValue;
std::string m_WriteCardId;
// ========== 单块操作超时控制 ==========
std::chrono::steady_clock::time_point m_BlockOpStartTime; // 当前块操作开始时间
uint8_t m_CurrentOperatingBlock = 0; // 当前正在操作的块号
bool m_BlockOperationPending = false; // 当前是否存在待读写响应
PendingCommand m_PendingCommand = PendingCommand::None;
uint8_t m_PendingBlock = 0;
uint8_t m_ReadBlockRetryCount = 0;
uint64_t m_OperationSequence = 0;
std::vector<uint8_t> m_PendingReadResponse; // 超时跳转时准备的响应
std::vector<uint8_t> m_SkippedBlocks; // 【新增】记录跳过的超时块号
uint8_t chCRCHTalbe[256] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
uint8_t chCRCLTalbe[256] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
void CRC16(std::vector<uint8_t>& data);
};
#endif

@ -0,0 +1,329 @@
#include "Publisher.hpp"
#include <condition_variable>
#include <csignal>
#include <stdexcept>
#include <thread>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/log/Log.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
#include <fastdds/rtps/common/Types.hpp>
#include <fastdds/dds/core/Types.hpp>
#include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp"
#include "MsgHandler.hpp"
#include "DEBUG.hpp"
using namespace eprosima::fastdds::dds;
PublisherApp::PublisherApp(
const int& domain_id)
: factory_(nullptr)
, participant_(nullptr)
, publisher_(nullptr)
, topic_(nullptr)
, writer_(nullptr)
, type_(new WeighingSystem::ReadCardRspPubSubType())
, matched_(0)
, samples_sent_(0)
, stop_(false)
, queue_trigger_publisher_(nullptr)
, queue_trigger_topic_(nullptr)
, queue_trigger_writer_(nullptr)
, queue_trigger_type_(new Queue::QueueTriggerPubSubType())
, current_date_()
, sequence_num_(0)
, last_card_()
, current_message_id_()
, wait_end_time_(std::chrono::steady_clock::now() - std::chrono::seconds(10)) // 初始化为过去时间,启动时不等待
, last_trigger_card_()
, wait_active_(false) // 启动后不处于等待期,由 OnCardDetected 激活
{
// Create the participant
DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("ReadCard_pub_participant");
pqos.wire_protocol().builtin.discovery_config.leaseDuration = Duration_t(60, 0);
pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = Duration_t(30, 0);
factory_ = DomainParticipantFactory::get_shared_instance();
participant_ = factory_->create_participant(domain_id, pqos, nullptr, StatusMask::none());
if (participant_ == nullptr)
{
throw std::runtime_error("ReadCard Participant initialization failed");
}
// Register ReadCardRsp type
type_.register_type(participant_);
// Create the publisher (for ReadCardRsp)
PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT;
participant_->get_default_publisher_qos(pub_qos);
publisher_ = participant_->create_publisher(pub_qos, nullptr, StatusMask::none());
if (publisher_ == nullptr)
{
throw std::runtime_error("ReadCard Publisher initialization failed");
}
// Create the topic (ReadCardRsp)
TopicQos topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos);
topic_ = participant_->create_topic("ReadCardRsp", type_.get_type_name(), topic_qos);
if (topic_ == nullptr)
{
throw std::runtime_error("ReadCard Topic initialization failed");
}
// Create the data writer (ReadCardRsp)
DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT;
publisher_->get_default_datawriter_qos(writer_qos);
writer_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
writer_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
writer_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
writer_ = publisher_->create_datawriter(topic_, writer_qos, this, StatusMask::all());
if (writer_ == nullptr)
{
throw std::runtime_error("ReadCard DataWriter initialization failed");
}
// ── 创建 QueueTrigger 发布者 ──
queue_trigger_type_.register_type(participant_);
PublisherQos qt_pub_qos = PUBLISHER_QOS_DEFAULT;
participant_->get_default_publisher_qos(qt_pub_qos);
queue_trigger_publisher_ = participant_->create_publisher(qt_pub_qos, nullptr, StatusMask::none());
TopicQos qt_topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(qt_topic_qos);
queue_trigger_topic_ = participant_->create_topic(
"QueueTrigger",
queue_trigger_type_.get_type_name(),
qt_topic_qos);
DataWriterQos qt_writer_qos = DATAWRITER_QOS_DEFAULT;
queue_trigger_publisher_->get_default_datawriter_qos(qt_writer_qos);
qt_writer_qos.reliability().kind = RELIABLE_RELIABILITY_QOS;
qt_writer_qos.durability().kind = VOLATILE_DURABILITY_QOS;
qt_writer_qos.history().kind = KEEP_LAST_HISTORY_QOS;
queue_trigger_writer_ = queue_trigger_publisher_->create_datawriter(
queue_trigger_topic_, qt_writer_qos, this, StatusMask::all());
}
PublisherApp::~PublisherApp()
{
if (nullptr != participant_)
{
participant_->delete_contained_entities();
factory_->delete_participant(participant_);
}
}
void PublisherApp::on_publication_matched(
DataWriter* writer,
const PublicationMatchedStatus& info)
{
if (info.current_count_change == 1)
{
{
std::lock_guard<std::mutex> lock(mutex_);
matched_ = info.current_count;
}
DEBUG(writer->get_topic()->get_name() << " Publisher matched.");
cv_.notify_one();
}
else if (info.current_count_change == -1)
{
{
std::lock_guard<std::mutex> lock(mutex_);
matched_ = info.current_count;
}
DEBUG(writer->get_topic()->get_name() << " Publisher unmatched.");
}
}
void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
{
// ── 拉卡检测回调:替代方案下放给主循环处理,这里不再绑定 ──
// 真正的触发逻辑在 run() 主循环里:
// HandleDeviceMsg → 把卡号写入 handler->pending_trigger_card_
// 主循环检测字段非空 → PublishQueueTrigger + PauseAutoFind + 启动 3s 等待期
// Device->Core 的响应DDS 载荷index + map<string,sequence<octet>>
WeighingSystem::ReadCardRsp rsp;
while (!is_stopped())
{
if (handler->isOpen() == true)
{
// ── 处理设备消息FindCard 响应会更新 m_CardId 并写入 pending_trigger_card_ ──
if (handler->HandleDeviceMsg(rsp))
{
// 当前版本不主动读卡,设备消息主要是 FindCard 响应
rsp.msg().clear();
}
// ── 检测新卡:发 QueueTrigger + 启动 3s 等待期 ──
std::string cardToTrigger;
{
std::lock_guard<std::mutex> lock(handler->trigger_mtx_);
if (!handler->pending_trigger_card_.empty())
{
cardToTrigger = handler->pending_trigger_card_;
handler->pending_trigger_card_.clear(); // 消费掉
}
}
if (!cardToTrigger.empty())
{
// 防止同一张卡短时间内重复触发3 秒等待期内忽略)
auto now = std::chrono::steady_clock::now();
if (now < wait_end_time_ && cardToTrigger == last_trigger_card_)
{
DEBUG("Card " << cardToTrigger
<< " still in 3s wait period, skipping QueueTrigger");
}
else
{
PublishQueueTrigger(cardToTrigger);
// 暂停自动寻卡state 切到 AUTO_FINDm_AutoFind=false
// 阻止 3 秒等待期内 HandleDdsMsg 接收 read/write
handler->PauseAutoFind();
wait_end_time_ = now + std::chrono::seconds(10);
wait_active_ = true; // 标记等待期,主循环在 3s 后才调 ForceReset
last_trigger_card_ = cardToTrigger;
DEBUG("QueueTrigger sent for card=" << cardToTrigger
<< ", waiting 10s before resuming auto-find");
}
}
// ── 等待期检查 ──
auto now2 = std::chrono::steady_clock::now();
if (now2 >= wait_end_time_)
{
// 等待期刚结束:仅在这一次调用时恢复 AUTO_FIND
if (wait_active_)
{
static auto last_resume_log = std::chrono::steady_clock::time_point{};
if (last_resume_log.time_since_epoch().count() == 0
|| now2 - last_resume_log > std::chrono::seconds(60))
{
DEBUG("10s wait elapsed, resuming AUTO_FIND");
last_resume_log = now2;
}
handler->ForceResetToAutoFind();
wait_active_ = false;
}
// pending read response来自超时跳过
if (handler->HasPendingReadResponse())
{
auto pendingRsp = handler->GetPendingReadResponse();
if (!pendingRsp.empty())
{
rsp.msg()["read"] = pendingRsp;
rsp.index(handler->GetCurrentIndex());
DEBUG("Publishing pending read response (from timeout skip)");
writer_->write(&rsp);
rsp.msg().clear();
}
}
handler->AutoFindTick();
}
else
{
// ── 等待期内:不发 DDS、不触发读卡、不恢复自动寻卡 ──
auto remaining = std::chrono::duration_cast<std::chrono::milliseconds>(
wait_end_time_ - now2).count();
}
}
std::unique_lock<std::mutex> period_lock(mutex_);
cv_.wait_for(period_lock, std::chrono::milliseconds(10), [this]()
{
return is_stopped();
});
}
}
bool PublisherApp::is_stopped()
{
return stop_.load();
}
void PublisherApp::on_data_available(DataReader* /*reader*/)
{
// 不再订阅任何 DDS Topic无需处理
}
void PublisherApp::on_subscription_matched(
DataReader* /*reader*/,
const SubscriptionMatchedStatus& /*info*/)
{
// 不再订阅任何 DDS Topic无需处理
}
void PublisherApp::stop()
{
stop_.store(true);
cv_.notify_one();
}
std::string PublisherApp::GenerateMessageId(const std::string& card_number)
{
std::lock_guard<std::mutex> lock(id_mtx_);
time_t now = time(nullptr);
char date_buf[9];
strftime(date_buf, sizeof(date_buf), "%Y%m%d", localtime(&now));
std::string today(date_buf);
// 日期变了:重置序号,清空上次的 card 和 message_id
if (today != current_date_)
{
current_date_ = today;
sequence_num_ = 0;
last_card_.clear();
current_message_id_.clear();
}
// 同一天、相同卡号:复用上次的 message_id
if (!last_card_.empty() && card_number == last_card_ && !current_message_id_.empty())
{
DEBUG("GenerateMessageId: card unchanged (" << card_number << "), reuse " << current_message_id_);
return current_message_id_;
}
// 不同卡号:序号累加
sequence_num_++;
last_card_ = card_number;
char id[32];
snprintf(id, sizeof(id), "qm-%s-%06u", today.c_str(), sequence_num_);
current_message_id_ = std::string(id);
DEBUG("GenerateMessageId: new card=" << card_number
<< " -> " << current_message_id_);
return current_message_id_;
}
void PublisherApp::PublishQueueTrigger(const std::string& card_number)
{
Queue::QueueTrigger msg;
const std::string mid = GenerateMessageId(card_number);
msg.message_id(mid);
msg.card_number(card_number);
msg.device_id("3"); // 本机读卡器设备编号
msg.trigger_time(""); // 暂时为 null空字符串
queue_trigger_writer_->write(&msg);
DEBUG("Published QueueTrigger: message_id=" << mid
<< " card=" << card_number << " device_id=3");
}

@ -0,0 +1,87 @@
#ifndef FAST_DDS_GENERATED__PUBLISHERAPP_HPP
#define FAST_DDS_GENERATED__PUBLISHERAPP_HPP
#include <condition_variable>
#include <ctime>
#include <mutex>
#include <string>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriterListener.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "MsgHandler.hpp"
class PublisherApp : public eprosima::fastdds::dds::DataWriterListener,
public eprosima::fastdds::dds::DataReaderListener
{
public:
PublisherApp(
const int& domain_id);
~PublisherApp();
//! Publisher matched method
void on_publication_matched(
eprosima::fastdds::dds::DataWriter* writer,
const eprosima::fastdds::dds::PublicationMatchedStatus& info) override;
//! Run publisher
void run(std::shared_ptr<MsgHandler> handler);
//! Trigger the end of execution
void stop();
void on_data_available(
eprosima::fastdds::dds::DataReader* reader) override;
void on_subscription_matched(
eprosima::fastdds::dds::DataReader* reader,
const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) override;
//! 发布 QueueTrigger
void PublishQueueTrigger(const std::string& card_number);
private:
//! Return the current state of execution
bool is_stopped();
//! 生成 message_id相同卡号复用不同卡号累加跨日重置
std::string GenerateMessageId(const std::string& card_number);
std::shared_ptr<eprosima::fastdds::dds::DomainParticipantFactory> factory_;
eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Publisher* publisher_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataWriter* writer_;
eprosima::fastdds::dds::TypeSupport type_;
std::condition_variable cv_;
int32_t matched_;
std::mutex mutex_;
const uint32_t period_ms_ = 100;
uint16_t samples_sent_;
std::atomic<bool> stop_;
// ── QueueTrigger 发布者 ──
eprosima::fastdds::dds::Publisher* queue_trigger_publisher_;
eprosima::fastdds::dds::Topic* queue_trigger_topic_;
eprosima::fastdds::dds::DataWriter* queue_trigger_writer_;
eprosima::fastdds::dds::TypeSupport queue_trigger_type_;
// ── message_id 生成状态 ──
std::mutex id_mtx_;
std::string current_date_; // 当前日期 "YYYYMMDD"
uint32_t sequence_num_; // 当日序号,从 1 开始
std::string last_card_; // 上一次检测到的卡号
std::string current_message_id_;// 当前 message_id同卡复用
// ── 读卡触发逻辑:发 DDS 后等待 3 秒再恢复自动寻卡 ──
std::chrono::steady_clock::time_point wait_end_time_; // 等待结束时刻
std::string last_trigger_card_; // 上次触发时的卡号(防重)
bool wait_active_; // 是否处于"等待期",仅在 OnCardDetected 时置 true
};
#endif // FAST_DDS_GENERATED__PUBLISHERAPP_HPP

@ -0,0 +1,168 @@
#include "Subscriber.hpp"
#include <condition_variable>
#include <stdexcept>
#include <fastdds/dds/core/status/SubscriptionMatchedStatus.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include "WeighingDDSTypePubSubTypes.hpp"
#include "msg.hpp"
#include "DEBUG.hpp"
using namespace eprosima::fastdds::dds;
SubscriberApp::SubscriberApp(
const int& domain_id)
: factory_(nullptr)
, participant_(nullptr)
, subscriber_(nullptr)
, topic_(nullptr)
, reader_(nullptr)
, type_(new WeighingSystem::ReadCardReqPubSubType())
, samples_received_(0)
, stop_(false)
{
// Create the participant
DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
pqos.name("ReadCard_sub_participant");
pqos.wire_protocol().builtin.discovery_config.leaseDuration = Duration_t(60, 0);
pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = Duration_t(30, 0);
factory_ = DomainParticipantFactory::get_shared_instance();
participant_ = factory_->create_participant(domain_id, pqos, nullptr, StatusMask::none());
if (participant_ == nullptr)
{
throw std::runtime_error("InternalSystem::ReadCardReq Participant initialization failed");
}
// Register the type
type_.register_type(participant_);
// Create the subscriber
SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT;
participant_->get_default_subscriber_qos(sub_qos);
subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none());
if (subscriber_ == nullptr)
{
throw std::runtime_error("InternalSystem::ReadCardReq Subscriber initialization failed");
}
// Create the topic
TopicQos topic_qos = TOPIC_QOS_DEFAULT;
participant_->get_default_topic_qos(topic_qos);
topic_ = participant_->create_topic("ReadCardReq", type_.get_type_name(), topic_qos);
if (topic_ == nullptr)
{
throw std::runtime_error("InternalSystem::ReadCardReq Topic initialization failed");
}
// Create the reader
DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT;
subscriber_->get_default_datareader_qos(reader_qos);
reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
reader_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
reader_ = subscriber_->create_datareader(topic_, reader_qos, this, StatusMask::all());
if (reader_ == nullptr)
{
throw std::runtime_error("InternalSystem::ReadCardReq DataReader initialization failed");
}
}
SubscriberApp::~SubscriberApp()
{
if (nullptr != participant_)
{
// Delete DDS entities contained within the DomainParticipant
participant_->delete_contained_entities();
// Delete DomainParticipant
factory_->delete_participant(participant_);
}
}
void SubscriberApp::on_subscription_matched(
DataReader* reader,
const SubscriptionMatchedStatus& info)
{
if (info.current_count_change == 1)
{
DEBUG(reader->get_topicdescription()->get_name() << " Subscriber matched.");
}
else if (info.current_count_change == -1)
{
DEBUG(reader->get_topicdescription()->get_name() << " Subscriber unmatched.");
}
else
{
DEBUG(info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change");
}
}
void SubscriberApp::on_data_available(
DataReader* reader)
{
SampleInfo info;
std::string topic_name = reader->get_topicdescription()->get_name();
DEBUG(topic_name << " Topic receviced.");
if (topic_name == "ReadCardReq")
{
WeighingSystem::ReadCardReq sample_;
while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info)))
{
if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data)
{
{
std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_);
MsgData::ReadCardReq_queue_.push(std::move(sample_));
lock.unlock();
}
}
}
}
}
void SubscriberApp::run(std::shared_ptr<MsgHandler> handler)
{
while (!is_stopped())
{
std::unique_lock<std::mutex> lock(MsgData::queue_cv_mtx_, std::try_to_lock);
if (lock.owns_lock())
{
if (!MsgData::ReadCardReq_queue_.empty())
{
WeighingSystem::ReadCardReq req = std::move(MsgData::ReadCardReq_queue_.front());
MsgData::ReadCardReq_queue_.pop();
lock.unlock();
handler->HandleDdsMsg(req.msg(), req.index());
}
else
{
lock.unlock();
}
}
{
std::unique_lock<std::mutex> period_lock(terminate_cv_mtx_);
terminate_cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this](){return is_stopped();});
}
}
}
bool SubscriberApp::is_stopped()
{
return stop_.load();
}
void SubscriberApp::stop()
{
stop_.store(true);
terminate_cv_.notify_all();
}

@ -0,0 +1,56 @@
#ifndef FAST_DDS_GENERATED__SUBSCRIBERAPP_HPP
#define FAST_DDS_GENERATED__SUBSCRIBERAPP_HPP
#include <condition_variable>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include "WeighingDDSType.hpp"
#include "MsgHandler.hpp"
class SubscriberApp : public eprosima::fastdds::dds::DataReaderListener
{
public:
SubscriberApp(
const int& domain_id);
virtual ~SubscriberApp();
//! Subscription callback
void on_data_available(
eprosima::fastdds::dds::DataReader* reader) override;
//! Subscriber matched method
void on_subscription_matched(
eprosima::fastdds::dds::DataReader* reader,
const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) override;
//! Run subscriber
void run(std::shared_ptr<MsgHandler> handler);
//! Trigger the end of execution
void stop();
private:
//! Return the current state of execution
bool is_stopped();
std::shared_ptr<eprosima::fastdds::dds::DomainParticipantFactory> factory_;
eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Subscriber* subscriber_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataReader* reader_;
eprosima::fastdds::dds::TypeSupport type_;
uint16_t samples_received_;
std::atomic<bool> stop_;
uint32_t period_ms_ = 100;
mutable std::mutex terminate_cv_mtx_;
std::condition_variable terminate_cv_;
};
#endif // FAST_DDS_GENERATED__SUBSCRIBERAPP_HPP

@ -0,0 +1,189 @@
#include <csignal>
#include <cstring>
#include <functional>
#include <iostream>
#include <stdexcept>
#include <thread>
#include <fastdds/dds/log/Log.hpp>
#include "Subscriber.hpp"
#include "Publisher.hpp"
#include "SerialMsgHandler.hpp"
#include "msg.hpp"
#include "DEBUG.hpp"
using eprosima::fastdds::dds::Log;
std::function<void(int)> stop_handler;
void signal_handler(
int signum)
{
stop_handler(signum);
}
std::string parse_signal(
const int& signum)
{
switch (signum)
{
case SIGINT:
return "SIGINT";
case SIGTERM:
return "SIGTERM";
#ifndef _WIN32
case SIGQUIT:
return "SIGQUIT";
case SIGHUP:
return "SIGHUP";
#endif // _WIN32
default:
return "UNKNOWN SIGNAL";
}
}
std::queue<WeighingSystem::ReadCardReq> MsgData::ReadCardReq_queue_;
std::mutex MsgData::queue_cv_mtx_;
int main(int argc, char** argv)
{
auto ret = EXIT_SUCCESS;
std::shared_ptr<SubscriberApp> sub;
std::shared_ptr<PublisherApp> pub;
std::shared_ptr<MsgHandler> dev;
int domain_id = 0;
const char* interface = "serial";
const char* port = "ttyS1";
const char* baudrate = "9600";
const char* device = "RC522";
// std::map<uint8_t, std::vector<uint8_t>> password = {
// {0, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}}, // AUSEFT
// {1, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {2, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {3, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {4, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {5, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {6, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// {10, {0x41, 0x55, 0x53, 0x45, 0x46, 0x54}},
// };
std::map<uint8_t, std::vector<uint8_t>> password = {
{0, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}}, // B7ML5F
{1, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
{2, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
{3, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
{4, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
{5, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
//{6, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
{6, {0xB1, 0x0A, 0x23, 0xD1, 0x8F, 0x20}}, // B10A23D18F20
{10, {0x42, 0x37, 0x4D, 0x4C, 0x35, 0x46}},
};
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--domain") == 0 && i + 1 < argc)
{
domain_id = atoi(argv[++i]);
}
else if (strcmp(argv[i], "--interface") == 0 && i + 1 < argc)
{
interface = argv[++i];
}
else if (strcmp(argv[i], "--port") == 0 && i + 1 < argc)
{
port = argv[++i];
}
else if (strcmp(argv[i], "--baudrate") == 0 && i + 1 < argc)
{
baudrate = argv[++i];
}
else if (strcmp(argv[i], "--device") == 0 && i + 1 < argc)
{
device = argv[++i];
}
else if (strcmp(argv[i], "--version") == 0)
{
std::cout << "Vesrion: " << PROGRAM_VERSION << "\n";
return EXIT_SUCCESS;
}
else if (strcmp(argv[i], "--help") == 0)
{
std::cout << "Usage: [options]\n"
<< "Options:\n"
<< " --domain Set domain ID\n"
<< " --interface Set interface (e.g., serial)\n"
<< " --baudrate Set baudrate (e.g., 9600)\n"
<< " --port Set port name (e.g., ttyS1)\n"
<< " --device Set device name (e.g., RC522)\n"
<< " --version Show software Version\n"
<< " --help Show this help message\n";
return EXIT_SUCCESS;
}
else
{
std::cerr << "Unknown option: " << argv[i] << "\n";
std::cout << "Usage: [options]\n"
<< "Options:\n"
<< " --domain Set domain ID\n"
<< " --interface Set interface (e.g., serial)\n"
<< " --baudrate Set baudrate (e.g., 9600)\n"
<< " --port Set port name (e.g., ttyS1)\n"
<< " --device Set device name (e.g., RC522)\n"
<< " --version Show software Version\n"
<< " --help Show this help message\n";
return EXIT_FAILURE;
}
}
sub = std::make_shared<SubscriberApp>(domain_id);
pub = std::make_shared<PublisherApp>(domain_id);
dev = std::make_shared<SerialMsgHandler>();
dev->OpenPort(port, baudrate);
dev->SetDevice(device);
dev->StorePasswd(password);
// ========== 新增:保存端口名,供 SkipCurrentBlock 使用 ==========
dev->m_Port = port;
// ========== 设置卡检测回调,发布 QueueTrigger ==========
dev->OnCardDetected = [pub](const std::string& cardId) {
pub->PublishQueueTrigger(cardId);
};
if (!dev->InitSequence())
{
DEBUG("Device initialization failed, exiting.");
return EXIT_FAILURE;
}
std::thread sub_thread(&SubscriberApp::run, sub, dev);
std::thread pub_thread(&PublisherApp::run, pub, dev);
DEBUG("Program is running. Please press Ctrl+C to stop at any time.");
stop_handler = [&](int signum)
{
std::cout << "\n" << parse_signal(signum) << " received, stopping execution." << std::endl;
sub->stop();
pub->stop();
};
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
#ifndef _WIN32
signal(SIGQUIT, signal_handler);
signal(SIGHUP, signal_handler);
#endif // _WIN32
sub_thread.join();
pub_thread.join();
Log::Reset();
return ret;
}

@ -0,0 +1,14 @@
#ifndef _MSG_HPP_
#define _MSG_HPP_
#include <queue>
#include <mutex>
#include "WeighingDDSType.hpp"
class MsgData {
public:
static std::queue<WeighingSystem::ReadCardReq> ReadCardReq_queue_;
static std::mutex queue_cv_mtx_;
};
#endif

@ -0,0 +1,121 @@
# ReadCard 程序流程文档
## 启动流程
```
main()
├─ OpenPort(port, baudrate) 打开串口
├─ SetDevice(device) 设置设备名
├─ StorePasswd(password) 存储扇区密码表
├─ InitSequence() 初始化序列(同步阻塞)
│ ├─ StopCard() → 等待应答 (3s超时)
│ ├─ SetPasswd(1) → 等待应答
│ ├─ SetPasswd(2) → 等待应答
│ ├─ SetPasswd(3) → 等待应答
│ ├─ SetPasswd(4) → 等待应答
│ ├─ SetPasswd(5) → 等待应答
│ ├─ SetPasswd(10) → 等待应答
│ └─ FindCard() 发出首次寻卡, AutoFind=true
│ (任一步失败 → 程序退出)
├─ 启动 sub_thread DDS命令接收线程
└─ 启动 pub_thread 设备响应发布线程
```
## 运行时两个线程
```
sub_thread (DDS命令接收) pub_thread (设备响应发布, 100ms周期)
│ │
│ 收到 ReadCardReq │ HandleDeviceMsg()
│ → HandleDdsMsg() │ → RecvDeviceMsg() 读串口
│ │ → ParseDeviceMsg() 解析响应
│ │ → 有数据则 writer_->write() 发布DDS
│ │
│ │ AutoFindTick()
│ │ → AutoFind开启时按间隔发FindCard
```
## DDS 对外接口
### 订阅 Topic: `ReadCardReq`
| 命令 | 参数 | 行为 |
|------|------|------|
| `"find"` | 无 | 清空重复卡记录,启动自动寻卡 |
| `"read"` | `{扇区号}` | 暂停自动寻卡,读指定扇区 |
| `"write"` | `{扇区号, 数据...}` | 暂停自动寻卡,写指定扇区 |
| `"stop"` | 无 | 停止自动寻卡 |
| `"beep"` | `{时长}` 或空 | 暂停自动寻卡,蜂鸣(默认0x0F) |
| `"reset"` | 无 | 暂停自动寻卡,清空串口缓冲区 |
### 发布 Topic: `ReadCardRsp`
| 响应 | 内容 | 说明 |
|------|------|------|
| `"find"` | 成功:`{卡号4字节}` 失败:`{错误码}` | 寻卡结果 |
| `"read"` | 成功:`{数据17字节}` 失败:`{错误码}` | 读卡结果 |
| `"write"` | `{状态码}` | 写卡结果 |
| `"stop"` | `{状态码}` | 停止结果 |
| `"beep"` | `{状态码}` | 蜂鸣结果 |
## 自动寻卡状态机
```
┌──────────────────────────┐
│ AutoFind = true │
│ (自动寻卡运行中) │
│ │
│ AutoFindTick按间隔 │
│ 发送FindCard │
└──┬────────┬───────────┬──┘
│ │ │
寻卡失败 │ 寻卡成功(新卡)│ 寻卡成功(重复卡)
interval=500ms│ AutoFind=false│ interval=5000ms
继续重试 │ 发布卡号 │ 不发布,继续寻卡
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │AutoFind=false│ │
│ │(等待业务处理)│ │
│ └──┬─────┬───┘ │
│ │ │ │
│ DDS下发 DDS下发 │
│ read write │
│ │ │ │
│ ▼ ▼ │
│ 设备响应返回 │
│ AutoFind=true │
│ interval=500ms │
│ │ │
└──────┘──────────────┘
(回到自动寻卡状态)
特殊命令:
"stop" → AutoFind=false, 完全停止寻卡
"find" → AutoFind=true, 清空PreCard, 重新开始寻卡
"beep"/"reset" → AutoFind=false, 暂停寻卡(需DDS重发find恢复)
```
## 定时间隔策略
| 时机 | 间隔 | 说明 |
|------|------|------|
| 发送FindCard后 | 5000ms | 超时保护,无应答则重发 |
| 寻卡失败 | 500ms | 快速重试 |
| 重复刷卡 | 5000ms | 同一张卡不重复处理 |
| 读写完成恢复 | 500ms | 业务结束后快速恢复寻卡 |
## 启动参数
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--domain` | 0 | DDS域ID |
| `--interface` | serial | 接口类型 |
| `--port` | ttyS1 | 串口端口 |
| `--baudrate` | 9600 | 波特率 |
| `--device` | RC522 | 设备名称 |
| `--version` | - | 显示版本号 |
| `--help` | - | 显示帮助信息 |

@ -0,0 +1,51 @@
./Weigh --port ttyS5 --device Keli
./Print --port ttyS2 --device NP80A
./Core --addr mqtt://192.168.1.1:1883
./Weigh --port ttyS3 --device Keli
./Print --port ttyS2 --device NP80A
./Core --addr mqtt://10.180.4.101:1883
./print-test publisher
{
"bar_ctrl":
{
"FrontBar": "down",
"BackBar": "down"
}
}
{
"light_ctrl":
{
"FrontLED": "red",
"BackLED": "red"
}
}
ScaleInfo VOLATILE_DURABILITY_QOS
ScaleCommand VOLATILE_DURABILITY_QOS
WeightInfoOk VOLATILE_DURABILITY_QOS
WeightInfoError VOLATILE_DURABILITY_QOS
BarCommandUpdate VOLATILE_DURABILITY_QOS
LightsCommandUpdate VOLATILE_DURABILITY_QOS
InfraredCommandUpdate VOLATILE_DURABILITY_QOS
BarUpdate TRANSIENT_LOCAL_DURABILITY_QOS
LightsUpdate TRANSIENT_LOCAL_DURABILITY_QOS
InfraredUpdate TRANSIENT_LOCAL_DURABILITY_QOS
LicenseSnapUpdate VOLATILE_DURABILITY_QOS
Voice VOLATILE_DURABILITY_QOS
SummaryUpdate VOLATILE_DURABILITY_QOS
./Core --domain 12 &
./GateCtrl --domain 12 &
./HttpServer --domain 12 --port 8081 &
./Print --domain 12 --port ttyS2 &
./Weigh --domain 12 --port ttyS3 &

@ -127,7 +127,10 @@ int MsgHandler::RecvMsg(std::vector<uint8_t>& data, int timeoutMs)
} }
// 有数据可读 // 有数据可读
uint8_t bytes; //uint8_t bytes;
int bytes;
if (ioctl(fd, FIONREAD, &bytes) < 0) if (ioctl(fd, FIONREAD, &bytes) < 0)
{ {
perror("ioctl FIONREAD失败"); perror("ioctl FIONREAD失败");
@ -141,6 +144,9 @@ int MsgHandler::RecvMsg(std::vector<uint8_t>& data, int timeoutMs)
return -1; return -1;
} }
data.resize(bytesRead); // 调整 data 大小为实际读取的字节数
return bytesRead; return bytesRead;
} }
@ -171,7 +177,8 @@ bool MsgHandler::get_frame(std::vector<uint8_t>& frame, uint8_t frame_size, uint
} }
// 检查是否有足够的数据(至少一个完整帧) // 检查是否有足够的数据(至少一个完整帧)
if (m_WeightData.size() >= 12) //if (m_WeightData.size() >= 12)
if (m_WeightData.size() >= frame_size)
{ {
// 检查结束字节 // 检查结束字节
if (m_WeightData[frame_size - 1] == end) if (m_WeightData[frame_size - 1] == end)
@ -490,13 +497,44 @@ bool MsgHandler::get_weight_2(float& weight, std::vector<uint8_t>& frame)
} }
} }
int decimalPos = frame[1]&0x07 - 2; // ========== 新增:调试打印 weightDigits ==========
if (decimalPos < 0) //std::cout << "[DEBUG] weightDigits='" << weightDigits << "' (len=" << weightDigits.size() << ")" << std::endl;
// int decimalPos = frame[1]&0x07 - 2;
// if (decimalPos < 0)
// {
// decimalPos = 0;
// }
// 判断是否为国产仿制协议:
// 特征frame[1] == '1' 且 frame[2] == '0'(固定标识"10"
// 这种情况下没有小数点指示,整数就是 kg
int decimalPos = 0;
bool is_domestic_clone = (frame[1] == '1' && frame[2] == '0');
if (!is_domestic_clone)
{ {
decimalPos = 0; // 标准 Toledo按字节 [1] 的 ASCII 数字解析小数位数
if (frame[1] >= '0' && frame[1] <= '4')
{
decimalPos = frame[1] - '0';
} }
}
// 否则 decimalPos = 0国产仿制视为整数
// 防止 divisors 数组越界
if (decimalPos < 0) decimalPos = 0;
if (decimalPos > 5) decimalPos = 5;
// =================================
raw_value = std::stof(weightDigits); raw_value = std::stof(weightDigits);
// ========== 新增:调试打印 raw_value ==========
//std::cout << "[DEBUG] raw_value=" << raw_value << " decimalPos=" << decimalPos << std::endl;
weight = raw_value / divisors[decimalPos]; weight = raw_value / divisors[decimalPos];
if (frame[2] & 0x02) if (frame[2] & 0x02)
@ -504,6 +542,9 @@ bool MsgHandler::get_weight_2(float& weight, std::vector<uint8_t>& frame)
weight = 0 - weight; weight = 0 - weight;
} }
return true; return true;
} }
@ -515,6 +556,26 @@ bool MsgHandler::HandleDeviceMsg(T& msg)
if (RecvDeviceMsg(m_Data, 100) > 0) if (RecvDeviceMsg(m_Data, 100) > 0)
{ {
// 清空累积,避免错位数据影响
m_WeightData.clear();
// ========== 新增:每次读取前重新配置串口 ==========
// SerialMsgHandler* serial = dynamic_cast<SerialMsgHandler*>(this);
// if (serial != nullptr) {
// serial->refreshPort();
// }
// ========== 新增:调试打印原始数据 ==========
// std::cout << "[DEBUG] Recv bytes: " << m_Data.size() << " Data: ";
// for (size_t i = 0; i < m_Data.size() && i < 32; i++) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)m_Data[i] << " ";
// }
// std::cout << std::dec << std::endl;
// ==========================================
m_WeightData.insert(m_WeightData.end(), m_Data.begin(), m_Data.end()); m_WeightData.insert(m_WeightData.end(), m_Data.begin(), m_Data.end());
} }
@ -531,6 +592,14 @@ bool MsgHandler::HandleDeviceMsg(T& msg)
{ {
if (get_frame(frame, 17, STX, CR) == true) if (get_frame(frame, 17, STX, CR) == true)
{ {
// ========== 新增:调试打印 frame 内容 ==========
// std::cout << "[DEBUG] Frame extracted: ";
// for (size_t i = 0; i < frame.size(); i++) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)frame[i] << " ";
// }
// std::cout << std::dec << " (size=" << frame.size() << ")" << std::endl;
return get_weight_2(msg, frame); return get_weight_2(msg, frame);
} }
} }

@ -214,6 +214,11 @@ void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
if (handler->HandleDeviceMsg(weight) == true) if (handler->HandleDeviceMsg(weight) == true)
{ {
bool success = detector.processWeight(weight); bool success = detector.processWeight(weight);
// ========== 调试打印1串口收到数据 ==========
//std::cout << "[DEBUG] Recv from ttyS3, weight=" << weight << std::endl;
if (!success) if (!success)
{ {
std::cout << "Failed to process weight!" << std::endl; std::cout << "Failed to process weight!" << std::endl;
@ -253,18 +258,24 @@ void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
if (detector.isStable()) if (detector.isStable())
{ {
info.WeightOK() = true; info.WeightOK() = true;
info.Value() = weight; info.Value() = weight / 1000.0f;
info.StableValue() = weight; info.StableValue() = weight / 1000.0f;
} }
else else
{ {
info.WeightOK() = false; info.WeightOK() = false;
info.Value() = weight; info.Value() = weight / 1000.0f;
info.StableValue() = 0; info.StableValue() = 0;
} }
if (send_time >= 50) if (send_time >= 50)
{ {
// ========== 调试打印2DDS发布前 ==========
// std::cout << "[DEBUG] DDS Publish: Value=" << info.Value()
// << " StableValue=" << info.StableValue()
// << " HasVehicle=" << info.HasVehicle() << std::endl;
writer_->write(&info); writer_->write(&info);
send_time = 0; send_time = 0;
} }
@ -276,6 +287,14 @@ void PublisherApp::run(std::shared_ptr<MsgHandler> handler)
send_time = 50; send_time = 50;
} }
// ========== 调试打印3主循环心跳 ==========
// static int heartbeat = 0;
// heartbeat++;
// if (heartbeat % 100 == 0) {
// std::cout << "[DEBUG] Main loop alive, heartbeat=" << heartbeat << std::endl;
// }
// Wait for period or stop event // Wait for period or stop event
std::unique_lock<std::mutex> period_lock(mutex_); std::unique_lock<std::mutex> period_lock(mutex_);
cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this]() cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [this]()

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Loading…
Cancel
Save