Commit Iniziale

This commit is contained in:
2019-10-21 11:37:31 +02:00
commit 44ac6e8802
56 changed files with 32022 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.project

BIN
PiantaRobot_Alto.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

80
RoboGlue.pro Normal file
View File

@@ -0,0 +1,80 @@
#-------------------------------------------------
#
# Project created by QtCreator 2019-01-21T13:30:50
#
#-------------------------------------------------
QT += core \
gui \
network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = RoboGlue
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
QMAKE_CXXFLAGS += -Wno-unused-parameter \
-Wno-unused-variable
SOURCES += \
main.cpp \
libURcom/clientMessage.cpp \
libURcom/URCLinterface.cpp \
init/roboglue_init.cpp \
com/roboglue_com.cpp \
gui/roboglue_gui.cpp \
main/roboglue_main.cpp \
shared/roboglue_shared.cpp \
track/roboglue_track.cpp \
com/mqtt_callback.cpp
HEADERS += \
libURcom/clientMessage.h \
libURcom/packagetypes.h \
libURcom/URCLinterface.h \
init/roboglue_init.h \
com/roboglue_com.h \
gui/roboglue_gui.h \
main/roboglue_main.h \
shared/roboglue_shared.h \
track/roboglue_track.h \
libJson/json.hpp \
com/mqtt_callback.h
FORMS += \
init/roboglue_init.ui \
gui/roboglue_gui.ui
LIBS += -lboost_system \
-lboost_thread \
-lboost_chrono \
-lpthread \
-lpaho-mqttpp3 \
-lpaho-mqtt3a
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
SUBDIRS += \
RoboGlue.pro
RESOURCES += \
roboglue_resources.qrc

522
RoboGlue.pro.user Normal file
View File

@@ -0,0 +1,522 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.2, 2019-07-10T11:42:03. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{3d769059-8219-4d9e-8059-e25a3e815e0e}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</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">qt</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="int" 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.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="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</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="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.12.1 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.12.1 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5121.gcc_64_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_0_GCC_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_1_GCC_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_1_GCC_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RoboGlue</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/RoboGlue/RoboGlue.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">RoboGlue.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_0_GCC_64bit-Debug</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.1</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{b917fd33-cfca-4cf9-a8d9-025510846768}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RoboGlue</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/RoboGlue/RoboGlue.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">RoboGlue.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">2</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">20</value>
</data>
<data>
<variable>Version</variable>
<value type="int">20</value>
</data>
</qtcreator>

270
RoboGlue.pro.user.07204ca Normal file
View File

@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.1, 2019-02-01T14:15:49. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{07204ca4-3ee6-4fe3-8a4e-4be58efc8824}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</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">qt</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="int" 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.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="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</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="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.12.0 (gcc_64)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.12.0 (gcc_64)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{a7ccd2d8-4d86-488f-8674-e3cd54db0525}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Qt_5_12_0_gcc_64_temporary-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_0_GCC_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</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="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</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.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">2</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">true</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RoboGlue</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/RoboGlue/RoboGlue.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">RoboGlue.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/emanuele/Documents/GestioneMacchine/Robot_Incollaggio/Software/QtCreator-Workspace/build-RoboGlue-Desktop_Qt_5_12_0_GCC_64bit-Debug</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">20</value>
</data>
<data>
<variable>Version</variable>
<value type="int">20</value>
</data>
</qtcreator>

View File

@@ -0,0 +1,25 @@
#include "ros/ros.h"
#include "std_msgs/String.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "RoboGlue_Publisher");
ros::NodeHandle nh;
ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
std_msgs::String msg;
msg.data = "hello world";
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}

25
com/mqtt_callback.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "mqtt_callback.h"
mqtt_callback::mqtt_callback(mqtt::async_client *cli, std::shared_ptr<spdlog::logger> log) {
//initialize client pointer
cli_=cli;
log_=log;
}
void mqtt_callback::connected(const mqtt::string &cause) {
log_->info("MQTT client Connected: {}", cause.c_str());
}
void mqtt_callback::connection_lost(const mqtt::string &cause) {
log_->info("MQTT client Disconnected {}", cause.c_str());
}
void mqtt_callback::message_arrived(mqtt::const_message_ptr msg) {
log_->debug("Message Arrived: topic->{} - message->{}",
msg->get_topic(), msg->to_string());
}
void mqtt_callback::delivery_complete(mqtt::delivery_token_ptr tok) {
log_->trace("Message Delivery complete \n tok: {}", tok->get_message_id());
}

23
com/mqtt_callback.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef MQTT_CALLBACK_H
#define MQTT_CALLBACK_H
#include <mqtt/client.h>
#include <mqtt/callback.h>
#include <spdlog/logger.h>
class mqtt_callback : public virtual mqtt::callback {
private:
mqtt::async_client *cli_ = nullptr;
std::shared_ptr<spdlog::logger> log_;
public:
mqtt_callback(mqtt::async_client *cli, std::shared_ptr<spdlog::logger> log);
void connected(const mqtt::string &cause) override;
void connection_lost(const mqtt::string &cause) override;
void message_arrived(mqtt::const_message_ptr msg) override;
void delivery_complete(mqtt::delivery_token_ptr tok) override;
};
#endif

390
com/roboglue_com.cpp Normal file
View File

@@ -0,0 +1,390 @@
#include "roboglue_com.h"
RoboGlue_COM::RoboGlue_COM (RoboGlue_SHARED *mem): m(mem) {
//////// SETUP LOGGER //////////
liblog = spdlog::stdout_logger_mt("URcom_liblog");
modlog = spdlog::stdout_logger_mt("RoboGlue_comlog");
liblog->set_level(spdlog::level::info);
modlog->set_level(spdlog::level::debug);
///////// INITIALIZE TCP SERVER ///////////
server = new QTcpServer(this);
server->listen(QHostAddress::Any, 9000);
connect(server, SIGNAL(newConnection()), this, SLOT(on_internalRobotConnect()));
modlog->info("COM started");
//////// INITIALIZE MQTT CONNECTOR ///////
client = new mqtt::async_client(std::string("tcp://localhost:1883"),"");
callback = new mqtt_callback(client,modlog);////////////////////////////////////////////////
//////// END EXTERNAL PUBLIC SLOTS /////////////
////////////////////////////////////////////////
baseMsg = m->commonSettings.baseMessage;
baseMsg["command"]=nullptr;
baseMsg["params"]=nullptr;
//////// INITIALIZE TIMED CALLBACK FUNCTIONS //////
coordSendTimer = new QTimer(this);
connect(coordSendTimer, SIGNAL(timeout()), this, SLOT(timed_sendCoordinates()));
}
void RoboGlue_COM::run() {
unsigned char attempt = 0;
/// START MQTT CLIENT ////
client->set_callback(*callback);
client->connect()->wait();
// subscrbe to mqtt topics
std::vector<std::string> subList = m->comSettings.subList;
for (uint i=0; i < subList.size(); i++){
client->subscribe(subList[i],0);
}
client->start_consuming();
/// AUTOCONNECT ROBOT INTERFACE ///
if(m->comSettings.connection.autoConnect) this->on_connect(QString(m->comSettings.connection.robotIp.c_str()),
m->comSettings.connection.robotPort,
m->comSettings.connection.retry);
/// THREAD LOOP ///
while(this->isRunning){
// if host is not connected and the reader thread is stopped do nothing
if (!this->isConnected & !this->isReading) {
msleep(100);
}
// if host is connected but reader thread is not started, start it
else if (this->isConnected & !this->isReading) {
this->isConnected=false;
// create new robot interface
interface = new UR_CLinterface(liblog);
// try connect to robot
while (!this->isConnected & (attempt++ < m->comSettings.connection.retry)){
attempt = 0;
modlog->debug("Connection Attempt:{0}",attempt);
try {
this->isConnected = interface->connect(m->comSettings.connection.robotIp.c_str(),
m->comSettings.connection.robotPort);
} catch (boost::system::system_error &e){
modlog->error("Connection Failed:\n {}", e.what());
}
}
if (this->isConnected & ! this->isReading) {
// create new reader thread and connect new data signal
modlog->info("Interface Connected");
readerThr = new readerThread(&this->isReading, interface, &localData);
// connect readerThread newdata signal
connect(readerThr, SIGNAL(newDataAvailable()), this, SLOT(on_internalNewData()));
readerThr->start();
modlog->debug("ReaderThread is Working");
this->isReading = true;
} else modlog->error("Connection failed");
}
// if host is connected and reader is running, do nothing
else if (this->isConnected & this->isReading) {
if (robotConnected){
if(robotIN->bytesAvailable()){
robotRequest = robotIN->readAll().toStdString();
robotRequest.pop_back();
modlog->info("robotMessage {}", robotRequest.c_str());
processRobotRequest(robotRequest);
}
}
emit com_heartBeat();
msleep(10);
}
// if host is to be disconnected but still reading, stop reading and disconnect host
else if (!this->isConnected & this->isReading){
// disable reading, should stop reader thread, disconnect new data signal
disconnect(readerThr, SIGNAL(newDataAvailable()), this, SLOT(on_internalNewData()));
this->isReading = false;
readerThr->wait();
modlog->debug("ReaderThread is Stopped");
// wait until thread exits
this->isConnected=false;
interface->disconnect();
modlog->info("Interface Disconnected");
// schedule readerThread for deletion;
readerThr->deleteLater();
// delete and rebuild interface for next connection;
delete interface;
interface = nullptr;
}
}
if (isConnected) {
robotIN->disconnectFromHost();
robotIN->deleteLater();
server->deleteLater();
on_disconnect();
readerThr->wait();
coordSendTimer->stop();
}
if (interface != nullptr) delete interface;
if (coordSendTimer != nullptr) delete coordSendTimer;
spdlog::drop("URcom_liblog");
spdlog::drop("RoboGlue_comlog");
}
/////////////////////////////////////////////////
//////////////////// READER THREAD //////////////
////////////////////////////////////////////////
void readerThread::run(){
this->loopRead();
}
void readerThread::loopRead() {
while(*this->isReading){
interface->readData();
interface->parseData();
*dataOut=interface->clientData;
// emit signal every new data received
emit newDataAvailable();
}
}
/////////////////////////////////////////////////
///////////////END READER THREAD////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
/////////////// MQTT FUNCTIONS /////////////////
////////////////////////////////////////////////
void RoboGlue_COM::MQTTpublish(json msg, string topic) {
std::string msgstr = msg.dump();
mqtt::token_ptr tok = client->publish(mqtt::make_message(topic,msgstr));
modlog->trace("Published: id:{0}, topic:{1}, msg:{2}",
tok->get_message_id(), tok->get_topics(), msgstr);
}
////////////////////////////////////////////////
////////////END MQTT FUNCTIONS /////////////////
////////////////////////////////////////////////
void RoboGlue_COM::saveKinematicInfo() {
m->mutex.lock();
m->settings->beginGroup("robot");
m->settings->beginGroup("kine");
m->settings->beginWriteArray("dhtable");
for (int i=0; i<JOINT_NUMBER; i++) {
m->settings->setArrayIndex(i);
m->settings->setValue("dha", localData.configuration.kinematics.DHa[i]);
m->settings->setValue("dhd", localData.configuration.kinematics.DHd[i]);
m->settings->setValue("dhalpha", localData.configuration.kinematics.DHalpha[i]);
m->settings->setValue("dhtheta", localData.configuration.kinematics.DHtheta[i]);
}
m->settings->endArray();
m->settings->endGroup();
m->settings->endGroup();
m->mutex.unlock();
}
void RoboGlue_COM::saveConnectionInfo() {
m->mutex.lock();
m->settings->beginGroup("robot");
m->settings->beginGroup("connection");
m->settings->setValue("robotip",QString(m->comSettings.connection.robotIp.c_str()));
m->settings->setValue("robotport",m->comSettings.connection.robotPort);
m->settings->setValue("robotretry",m->comSettings.connection.retry);
m->settings->setValue("autoconnect",m->comSettings.connection.autoConnect);
m->settings->endGroup();
m->settings->endGroup();
m->mutex.unlock();
}
void RoboGlue_COM::processRobotRequest(std::string request) {
std::string response;
std::string varName;
std::string varValue;
std::vector<std::string> tokes;
m->mutex.lock();
// split command into tokes
boost::algorithm::split(tokes,request,boost::is_any_of(" "));
// process requested action
if (tokes[COMMAND] == "GET"){
modlog->debug("Robot GET Request");
varName = tokes[VARNAME];
response = varName + " ";
try {
response += std::to_string(m->robotVariables.at(varName));
} catch (std::out_of_range &e) {
modlog->error("{0}:{1}",e.what(), varName);
}
response.append("\n");
} else
if (tokes[COMMAND] == "SET") {
modlog->debug("Robot SET Request");
varName = tokes[VARNAME];
varValue = tokes[VALUE];
try {
// if variable does not exist insert it into map
m->robotVariables[varName] = std::stoi(varValue.c_str());
} catch (std::out_of_range &e) {
modlog->error("{0}:{1}",e.what(), varName);
}
} else {
modlog->debug("Robot GENERAL Request");
response = "generalrequest";
response.insert(0,&m->comSettings.connection.prefix);
response.append(&m->comSettings.connection.suffix);
}
m->mutex.unlock();
robotIN->write(response.c_str());
robotIN->flush();
}
////////////////////////////////////////////////
////////////INTERNAL PRIVATE SLOTS//////////////
////////////////////////////////////////////////
void RoboGlue_COM::on_internalRobotConnect() {
if(robotIN != nullptr) {
robotConnected = false;
delete robotIN;
}
modlog->info("Robot request connected");
robotIN = server->nextPendingConnection();
robotConnected = true;
}
void RoboGlue_COM::on_internalNewData(){
this->m->mutex.lock();
m->robotData=this->localData;
this->m->mutex.unlock();
emit com_newData();
// save DH matrix data;
if(isFirstMessage) {
this->saveKinematicInfo();
isFirstMessage = false;
}
}
void RoboGlue_COM::timed_sendCoordinates(){
QList<double> sp = this->lastCoord;
if (this->isCoordNew)
this->isCoordNew = false;
if (!sp.empty()){
modlog->trace("timedSendCoordinate");
baseMsg.clear();
baseMsg["type"] = "cartesian";
baseMsg["mode"] = "pos";
baseMsg["value"] = json();
baseMsg["value"]["x"] = sp[0];
baseMsg["value"]["y"] = sp[1];
baseMsg["value"]["z"] = sp[2];
baseMsg["value"]["rx"] = sp[3];
baseMsg["value"]["ry"] = sp[4];
baseMsg["value"]["rz"] = sp[5];
MQTTpublish(baseMsg, m->comSettings.pubList[m->comSettings.COORD]);
}
}
////////////////////////////////////////////////
////////END INTERNAL PRIVATE SLOTS//////////////
////////////////////////////////////////////////
void RoboGlue_COM::on_commonStatusChange() {
if (m->commonStatus.isRecording || m->commonStatus.isRealtime) {
if (!coordSendTimer->isActive()) coordSendTimer->start(100);
}
if (!m->commonStatus.isRecording && !m->commonStatus.isRealtime){
if (coordSendTimer->isActive()) coordSendTimer->stop();
}
}
void RoboGlue_COM::on_quit() {
this->isConnected=false;
client->disconnect();
while(this->isReading) msleep(100);
this->isRunning = false;
}
void RoboGlue_COM::on_connect(QString ip, uint port, uchar retry) {
modlog->debug("robotConnect Received");
if (!isConnected){
this->isConnected=true;
this->isReading=false;
this->isFirstMessage=true;
// update connection information for the thread
m->comSettings.connection.robotIp = ip.toStdString();
m->comSettings.connection.robotPort = port;
m->comSettings.connection.retry = retry;
// save connection info
saveConnectionInfo();
}
}
void RoboGlue_COM::on_disconnect() {
modlog->debug("robotDisconnect Received");
if(isConnected){
this->isConnected = false;
}
}
void RoboGlue_COM::on_sendURscript(QString command) {
modlog->debug("robotSendURscript Received");
if(isConnected){
//command sent directly trough interface, NOT ROS
this->interface->sendCommand(command.toStdString());
}
}
void RoboGlue_COM::on_sendROScommand(QString command, QVariantMap params) {
modlog->debug("robotSendCommand Received");
baseMsg.clear();
baseMsg["command"] = command.toStdString();
QJsonDocument jparam = QJsonDocument(QJsonObject::fromVariantMap(params));
baseMsg["params"] = json::parse(jparam.toJson().data());
MQTTpublish(baseMsg, m->comSettings.pubList[m->comSettings.COMM]);
}
void RoboGlue_COM::on_sendROScoordinates(QList<double> sp) {
this->lastCoord.clear();
this->lastCoord = sp;
this->isCoordNew = true;
}
void RoboGlue_COM::on_sendROSstate(QMap<std::string,bool> digital, QMap<std::string, uint16_t> analog){
modlog->debug("robotSendState Received");
baseMsg.clear();
baseMsg["digital"] = nlohmann::json();
baseMsg["analog"] = nlohmann::json();
for (auto di : digital.keys()) {
baseMsg["digital"][di] = digital[di];
}
}
////////////////////////////////////////////////
//////// END EXTERNAL PUBLIC SLOTS /////////////
////////////////////////////////////////////////
//void RoboGlue_COM::on_sendSetpointOLD(QList<double> sp) {
// std::string setpoint;
// struct {
// union{
// struct{
// uint32_t x,y,z,a,b,c,keepalive;
// };
// char bytes[28];
// };
// } setPointBytes;
// setPointBytes.keepalive=1;
// int32_t v;
// setpoint = "(";
// for(uchar i=0; i<JOINT_NUMBER; i++){
// v=static_cast<int32_t>(sp[i]*1000);
// if (i>2) v=boost::algorithm::clamp(v, -2680,2680);
// setpoint.append(std::to_string(v));
// boost::algorithm::replace_all(setpoint, ",",".");
// if(i<JOINT_NUMBER) setpoint.append("|");
// }
// setpoint.append("1");
// boost::algorithm::replace_all(setpoint,"|",",");
// setpoint.append(")");
// setPointBytes.x=htonl(static_cast<uint32_t>(sp[0]*1000));
// setPointBytes.y=htonl(static_cast<uint32_t>(sp[1]*1000));
// setPointBytes.z=htonl(static_cast<uint32_t>(sp[2]*1000));
// setPointBytes.a=htonl(static_cast<uint32_t>(sp[3]*1000));
// setPointBytes.b=htonl(static_cast<uint32_t>(sp[4]*1000));
// setPointBytes.c=htonl(static_cast<uint32_t>(sp[5]*1000));
// setPointBytes.keepalive=htonl(setPointBytes.keepalive);
// if(robotIN->write(setPointBytes.bytes,28))
// modlog->trace("Sent Setpoint {}",setpoint.c_str());
// robotIN->flush();
//}

157
com/roboglue_com.h Normal file
View File

@@ -0,0 +1,157 @@
#ifndef ROBOGLUE_COM_H
#define ROBOGLUE_COM_H
/*
* roboglue_com.cpp
*
* Created on: Jan 21, 2019
* Author: emanuele
*
* Modulo di comunicazione del software roboglue, è un thread che continua a leggere le ibformazioni del robot
* e le scrive nella memoria condivisa tra i moduli, rivece comandi sotto forma di segnali per inviare
* comandi URscript al controller
*
* 20190121 - Prima Scittura, incorpora un thread che si occupa solo della lettura dati,
* ad ora non finzionante.
* 20190122 - Il thread di lettura funziona correttamente ed è implementazione di QThread,
* ad ogni nuovo pacchetto letto viene emess il segnale newData();
* la classe readerThread contiene solo la funzione che viene spostata nel thread
* di lettura.
* Impostata la struttura comune a tutti i moduli.
* 20190123 - Impostati i segnalli per connessione e disconnessione comandata da GUI.
* 20190125 - Corretti alcuni bug che facevano crashare in caso di mancata connessione.
* Aggiunto un parametero nella configurazione che definisce il massimo raggio di reach
* del robot. Sarà sostituito da una tabella completa delle lunghezze dei bracci per
* il calcolo della cinematica inversa nel main.
* 20190128 - Inizio scrittura modulo tcpsocket per lo scambio dei consensi.
* 20190129 - Continua scrittura del modulo socket, le variabili di scambio con il robot sono
* in una mappa <NOME,VALORE> <std::string,int> per facilitaà di accesso
* (rif documenti URscript get_var(), set_var())
* 20190131 - Modifiche alla parte di comunicazione per usare i comandi servoj del robot come
* suggerito nelle librerie di ROS industrial.
* Ricerche iniziate su come usare MoveIT e ros indusrtial con il driver UR per
* la pianificazione e l'invio delle traiettorie. Il problema principale è che
* il driver per UR di ROS è datato e non funziona con il controller versione 5.2
* ROS indusrtial inoltre non è ancora compatibile con l'ultima versione di ROS
* e ubuntu 18.04. Altervativa valida porebbe essere usare solo MoveIT, vedrò.
* 20190208 - Implementazione della comunicazione ai moduli ros con mqtt
* 20190211 - Continua implementazione della comunicazione ai moduli ros (non ancora scritto)
* con mqtt. Tra Qt e ROS ci saranno 3 code "bidirezionali": COMANDO, COORDINATE, STATO
* per separare i flussi dei messaggi.
* I messaggi sono strutturati come json, fare riferimento al file roboglue_messaggi.txt
* per la specifica di formato.
* I seganli che arrivano portando i messaggi sono strutturati diversamente a seconda
* della coda di destinazione.
* 20190311 - La pubblicazione dei messaggi di coordinate verso ros deve essere a rateo costante
* indipendentemente dalla frequenza di ingresso
*/
#include <QObject>
#include <QThread>
#include <QTcpServer>
#include <QTcpSocket>
#include <QJsonObject>
#include <QJsonDocument>
#include <QList>
#include <QTimer>
#include <ctime>
#include <arpa/inet.h>
#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/clamp.hpp>
#include <boost/chrono.hpp>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <mqtt/async_client.h>
#include "mqtt_callback.h"
#include <libURcom/URCLinterface.h>
#include <shared/roboglue_shared.h>
#define COMMAND 0
#define VARNAME 1
#define VALUE 2
class RoboGlue_COM: public QThread {
Q_OBJECT
public:
RoboGlue_COM(RoboGlue_SHARED* mem = nullptr);
void run() override;
private:
shared_ptr<spdlog::logger> liblog;
shared_ptr<spdlog::logger> modlog;
RoboGlue_SHARED *m;
clientData_t localData;
QThread *readerThr = nullptr;
QTcpServer *server = nullptr;
QTcpSocket *robotIN = nullptr;
mqtt_callback *callback = nullptr;
mqtt::async_client* client = nullptr;
json baseMsg;
std::string robotRequest;
UR_CLinterface *interface = nullptr;
QTimer* coordSendTimer = nullptr;
QList<double> lastCoord;
bool isCoordNew = false;
bool isRunning = true;
bool isConnected = false;
bool isReading = false;
bool isNew = false;
bool isFirstMessage = true;
bool robotConnected = false;
void saveKinematicInfo();
void saveConnectionInfo();
void processRobotRequest(std::string);
void MQTTpublish(json msg, std::string topic);
signals:
void com_newData();
void com_heartBeat();
void com_newROScommand(QString, QVariantMap);
private slots:
void on_internalRobotConnect();
void on_internalNewData();
void timed_sendCoordinates();
public slots:
void on_quit();
void on_commonStatusChange(void);
void on_connect(QString ip = "", uint port = 0, uchar retry = 1);
void on_disconnect();
void on_sendURscript(QString command);
void on_sendROScommand(QString, QVariantMap);
void on_sendROScoordinates(QList<double> sp);
void on_sendROSstate(QMap<std::string, bool> digital, QMap<std::string, uint16_t> analog);
//void on_sendSetpointOLD(QList<double> sp);
};
class readerThread: public QThread{
Q_OBJECT
public:
readerThread(bool* r, UR_CLinterface* i, clientData_t* d){
this->isReading=r;
this->interface=i;
this->dataOut=d;
}
bool* isReading;
UR_CLinterface* interface;
clientData_t* dataOut;
void run() override;
void loopRead();
signals:
void newDataAvailable();
};
#endif // ROBOGLUE_COM_H

343
gui/roboglue_gui.cpp Normal file
View File

@@ -0,0 +1,343 @@
#include "roboglue_gui.h"
#include "ui_roboglue_gui.h"
RoboGlue_GUI::RoboGlue_GUI(RoboGlue_SHARED *mem) : m(mem) {
//////// SETUP LOGGER //////////
modlog = spdlog::stdout_logger_mt("RoboGlue_guilog");
spdlog::set_level(spdlog::level::debug);
modlog->info("GUI Started");
//////// SETUP USER INTERFACE ///////
ui=new Ui::RoboGlue_GUI;
ui->setupUi(this);
ui->frm_move->setStyleSheet("border-image: url(:/images/PiantaRobot_Alto.png) 0 0 0 0 stretch stretch");
//////// RESTORE UI STATE ////////////
ui->txt_roboIp->setText(QString(m->comSettings.connection.robotIp.c_str()));
ui->txt_robotPort->setText(QString::number(m->comSettings.connection.robotPort));
ui->chk_autoConnect->setChecked(m->comSettings.connection.autoConnect);
//////// ENABLE HOVERING EVENT OVER DEFINED AREA //////////////
ui->frm_move->installEventFilter(this);
//////// CONNECT SIGNALS & SLOTS ///////
connect(this, SIGNAL(destroyed()),
this, SLOT(deleteLater()), Qt::ConnectionType::QueuedConnection);
connect(this, SIGNAL(pad_hoverEvent(QEvent *)),
this, SLOT(on_pad_hoverEvent(QEvent *)));
/////// READ NAME DEFINITION JSON FILE //////////
try {
QFile fp(QString(m->guiSettings.namePath.c_str()));
fp.open(QFile::ReadOnly | QFile::Text);
QByteArray rawdata= fp.readAll();
std::string strdata= rawdata.toStdString();
nameDefinitions = json::parse(strdata.c_str());
fp.close();
} catch (json::exception e){
modlog->error("Unable to parse name definitions:\n\t{}",e.what());
}
}
RoboGlue_GUI::~RoboGlue_GUI() {
spdlog::drop("RoboGlue_guilog");
delete ui;
}
bool RoboGlue_GUI::eventFilter(QObject *obj, QEvent *event){
if(obj == static_cast<QObject *>(ui->frm_move))
if(event->type()==event->MouseMove || event->type()==event->MouseButtonPress
|| event->type()==event->KeyPress){
event->accept();
emit pad_hoverEvent(event);
}
return QWidget::eventFilter(obj, event);
}
QVariantMap RoboGlue_GUI::getLockAxes() {
QVariantMap param;
param["lx"]=ui->chk_lockX->isChecked();
param["ly"]=ui->chK_lockY->isChecked();
param["lz"]=ui->chk_lockZ->isChecked();
param["lrx"]=ui->chk_lockRX->isChecked();
param["lry"]=ui->chk_lockRY->isChecked();
param["lrz"]=ui->chk_lockRZ->isChecked();
return param;
}
void RoboGlue_GUI::enableLockAxes() {
ui->chk_lockX->setEnabled(true);
ui->chK_lockY->setEnabled(true);
ui->chk_lockZ->setEnabled(true);
ui->chk_lockRX->setEnabled(true);
ui->chk_lockRY->setEnabled(true);
ui->chk_lockRZ->setEnabled(true);
}
void RoboGlue_GUI::disableLockAxes(){
ui->chk_lockX->setEnabled(false);
ui->chK_lockY->setEnabled(false);
ui->chk_lockZ->setEnabled(false);
ui->chk_lockRX->setEnabled(false);
ui->chk_lockRY->setEnabled(false);
ui->chk_lockRZ->setEnabled(false);
}
////////////////////////////////////////////////
////////////INTERNAL PRIVATE SLOTS//////////////
////////////////////////////////////////////////
void RoboGlue_GUI::on_commonStatusChange() {
modlog->trace("on_commonStatusChange Received");
}
void RoboGlue_GUI::on_pad_hoverEvent(QEvent* e) {
QMouseEvent *mouse = static_cast<QMouseEvent *>(e);
QKeyEvent *key = static_cast<QKeyEvent *>(e);
static float zpos=0.5;
static bool trackEnable = false;
static QPointF lastPos;
QPointF p;
float limit = m->comSettings.kine.maxReach;
modlog->trace("event: {}",e->type());
if(e->type() == e->MouseMove){
QPointF pos = mouse->localPos();
qreal x = boost::algorithm::clamp(pos.x(),0,ui->frm_move->size().width());
qreal y = boost::algorithm::clamp(pos.y(),0,ui->frm_move->size().height());
p = QPointF(x,y);
} else if(e->type() == e->MouseButtonPress &&
(m->commonStatus.isRecording || m->commonStatus.isRealtime)) {
modlog->trace("mousebuttonevent {}", mouse->button());
if(!trackEnable){
trackEnable=true;
//mouse->setLocalPos(lastPos);
ui->frm_move->setFocus();
if (ui->btn_record->isEnabled()) ui->btn_record->setEnabled(false);
if (ui->btn_realtime->isEnabled()) ui->btn_realtime->setEnabled(false);
} else if(trackEnable){
trackEnable=false;
lastPos=mouse->pos();
if (m->commonStatus.isRecording) ui->btn_record->setEnabled(true);
if (m->commonStatus.isRealtime) ui->btn_realtime->setEnabled(true);
}
} else if (e->type()==e->KeyPress) {
modlog->trace("keyevent {}", key->key());
if(key->key() == 16777235)
if (zpos < limit) zpos=zpos+0.1;
if(key->key() == 16777237)
if (zpos > 0) zpos=zpos-0.1;
}
if(trackEnable && (m->robotVariables.at("RDY") == 1)) {
QTransform t=QTransform::fromTranslate(-ui->frm_move->size().width()/2,
-ui->frm_move->size().height()/2);
t = t * QTransform::fromScale(-limit/t.dx(),
-limit/t.dy());
QPointF q = t.map(p);
ui->lbl_posX->setText(QString("X: %1m").arg(q.x(),6));
ui->lbl_posY->setText(QString("Y: %1m").arg(-q.y(),6));
ui->lbl_posZ->setText(QString("Z: %1m").arg(zpos,6));
// FIXME
///////////////////////////////////////////////////////
////////////////// TEMPORARY SEND COORDINATES ////////
////////////////// TO ROBOT /////////////////////////
/// (TO BE IMPLEMENTED IN MAIN FOR KINEMATICKS CHECK)
if (q.x()>-limit && q.x()<limit && q.y()>-limit && q.y()<limit && zpos > 0 && zpos < limit){
QList<double> sp = {q.x(),-q.y(),zpos,1.57,-2.68,0};
emit sendROScoordinates(sp);
}
}
}
void RoboGlue_GUI::on_btn_sendCommand_clicked(){
modlog->debug("robotSendCommand Requested");
emit robotSendURscript(ui->txt_commandToSend->text());
}
void RoboGlue_GUI::on_btn_robotConnect_clicked() {
modlog->debug("robotConnect Requested");
emit robotConnect(ui->txt_roboIp->text(),
ui->txt_robotPort->text().toUInt(),
5); // default retry attempt to 5
}
void RoboGlue_GUI::on_btn_robotDisconnect_clicked() {
modlog->debug("robotDisconnect Requested");
emit robotDisconnect();
}
void RoboGlue_GUI::on_chk_autoConnect_clicked(bool checked) {
m->comSettings.connection.autoConnect = checked;
m->settings->beginGroup("robot");
m->settings->beginGroup("connection");
m->settings->setValue("autoconnect", checked);
m->settings->endGroup();
m->settings->endGroup();
}
void RoboGlue_GUI::on_btn_record_clicked() {
static bool recording = false;
QVariantMap param;
QVariantMap metadata;
modlog->debug("robotTrajectory Record");
param.insert("action", "");
if (!recording) {
m->commonStatus.isRecording = true;
recording = true;
param["action"] = "start";
param["lock"] = getLockAxes();
metadata["name"] = ui->txt_fileName->text();
metadata["code"] = QUuid::createUuid().toString();
metadata["ds"] = ui->spn_ds->value();
metadata["dt"] = ui->spn_dt->value();
param["metadata"] = metadata;
ui->btn_play->setEnabled(false);
ui->btn_realtime->setEnabled(false);
disableLockAxes();
} else {
m->commonStatus.isRecording = false;
recording = false;
param["action"]="stop";
ui->btn_play->setEnabled(true);
ui->btn_realtime->setEnabled(true);
enableLockAxes();
}
emit m->commonStatusChange();
emit sendROScommand("RECORD", param);
}
void RoboGlue_GUI::on_btn_play_clicked() {
static bool playing = false;
QVariantMap param;
QVariantMap metadata;
modlog->debug("robotTrajectory Replay");
if (!playing) {
m->commonStatus.isPlaying = true;
playing = true;
metadata["name"]=ui->txt_fileName->text();
param["action"]="start";
param["metadata"] = metadata;
param["lock"] = getLockAxes();
ui->btn_record->setEnabled(false);
ui->btn_realtime->setEnabled(false);
ui->btn_play->setText("Stop");
ui->txt_fileName->setEnabled(false);
disableLockAxes();
} else {
m->commonStatus.isPlaying = false;
playing = false;
param["action"] = "stop";
ui->btn_record->setEnabled(true);
ui->btn_realtime->setEnabled(true);
ui->btn_play->setText("Play");
ui->txt_fileName->setEnabled(true);
enableLockAxes();
}
emit m->commonStatusChange();
emit sendROScommand("PLAY", param);
}
void RoboGlue_GUI::on_btn_open_clicked() {
static bool fileOpen = false;
QVariantMap param;
QVariantMap metadata;
modlog->debug("robotTragectory Open");
if(!fileOpen){
m->commonStatus.isFileOpen = true;
fileOpen = true;
metadata["name"] = ui->txt_fileName->text();
metadata["plot"] = true;
param["action"] = "open";
param["metadata"] = metadata;
ui->btn_record->setEnabled(false);
ui->btn_realtime->setEnabled(false);
ui->btn_open->setText("Close");
ui->txt_fileName->setEnabled(false);
} else {
m->commonStatus.isFileOpen = false;
fileOpen = false;
param["action"] = "close";
ui->btn_record->setEnabled(true);
ui->btn_realtime->setEnabled(true);
ui->btn_open->setText("Open");
ui->txt_fileName->setEnabled(true);
}
emit m->commonStatusChange();
emit sendROScommand("OPEN", param);
}
void RoboGlue_GUI::on_btn_realtime_clicked() {
static bool realtime = false;
QVariantMap param;
QVariantMap lock;
modlog->debug("robotTrajectory Realtime");
if (!realtime){
realtime = true;
m->commonStatus.isRealtime = true;
param["action"] = "start";
param["lock"] = getLockAxes();
if (ui->rad_pos->isChecked()) param["mode"] = "pos";
else if (ui->rad_vel->isChecked()) param["mode"] = "vel";
ui->btn_play->setEnabled(false);
ui->btn_record->setEnabled(false);
disableLockAxes();
} else {
m->commonStatus.isRealtime = false;
realtime = false;
param["action"]="stop";
ui->btn_play->setEnabled(true);
ui->btn_record->setEnabled(true);
enableLockAxes();
}
emit m->commonStatusChange();
emit sendROScommand("REALTIME", param);
}
////////////////////////////////////////////////
////////END INTERNAL PRIVATE SLOTS//////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
////////////EXTERNAL PUBLIC SLOTS///////////////
////////////////////////////////////////////////
void RoboGlue_GUI::on_newRobotData() {
m->mutex.lock();
robotModeData_t mode = m->robotData.robotMode;
cartesianInfo_t cart = m->robotData.cartesianInfo;
jointData_t joint = m->robotData.jointData;
m->mutex.unlock();
//////////// mode info //////////
try {
ui->lbl_connected->setText(QString::number(mode.isRealRobotConnected));
ui->lbl_robotMode->setText(QString(nameDefinitions["robotModes"][std::to_string(mode.robotMode).c_str()].get<std::string>().c_str()));
ui->lbl_powerOn->setText(QString::number(mode.isRobotPowerOn));
ui->lbl_emeStop->setText(QString::number(mode.isEmergencyStopped));
ui->lbl_proStop->setText(QString::number(mode.isProtectiveStopped));
ui->lbl_programRunning->setText(QString::number(mode.isProgramRunning));
ui->lbl_controlMode->setText(QString(nameDefinitions["controlModes"][std::to_string(mode.controlMode).c_str()].get<std::string>().c_str()));
} catch (json::exception e){
modlog->error("Unable to find name: \n{}",e.what());
}
//////////// cartesian info //////////
ui->lbl_cartX->setText("X: "+QString::number(cart.cartPosition.X*1000)+QString(" mm"));
ui->lbl_cartY->setText("Y: "+QString::number(cart.cartPosition.Y*1000)+QString(" mm"));
ui->lbl_cartZ->setText("Z: "+QString::number(cart.cartPosition.Z*1000)+QString(" mm"));
ui->lbl_cartRX->setText("Rx: "+QString::number(cart.cartPosition.RX,'g',3)+QString(" rad"));
ui->lbl_cartRY->setText("Ry: "+QString::number(cart.cartPosition.RY,'g',3)+QString(" rad"));
ui->lbl_cartRZ->setText("Rz: "+QString::number(cart.cartPosition.RZ,'g',3)+QString(" rad"));
//////////// joint info //////////
ui->lbl_J1->setText("Base: " + QString::number(joint.jointParam[0].actual)+" rad");
ui->lbl_J2->setText("Shoulder: " + QString::number(joint.jointParam[1].actual)+" rad");
ui->lbl_J3->setText("Elbow: " + QString::number(joint.jointParam[2].actual)+" rad");
ui->lbl_J4->setText("Wrist1: " + QString::number(joint.jointParam[3].actual)+" rad");
ui->lbl_J5->setText("Wrist2: " + QString::number(joint.jointParam[4].actual)+" rad");
ui->lbl_J6->setText("Wrist3: " + QString::number(joint.jointParam[5].actual)+" rad");
}
////////////////////////////////////////////////
//////// END EXTERNAL PUBLIC SLOTS /////////////
////////////////////////////////////////////////

108
gui/roboglue_gui.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef ROBOGLUE_GUI_H
#define ROBOGLUE_GUI_H
/*
* roboglue_gui.cpp
*
* Created on: Jan 21, 2019
* Author: emanuele
*
* Interfaccia utente di roboglue, conterrà la visualizzazione grafica del robot e tutte le
* interfaccce per il richiamo e la registrazione dei programmi di incollaggio
* tutta la logica sarà deferita ad un modulo main.
*
* 20190121 - Prima Scittura
* 20190122 - Disegnata la prima interfaccia grafica a scopo di debug, stampa solo le informazioni
* relative alla posizione cartesiana del robot.
* Impostata la struttura comune a tutti i moduli.
* 20190123 - Aggiunti elementi all'interfaccia grafica, connessione, disconnessione, indirizzo
* e porta del robot.
* 20190124 - Aggiunta logica per mandare comandi URscript senza controllo di ortografia e validità,
* aggiunta la lettura di un file json che include i nomi degli stati di robot
* e controller per una migliore leggibilità dell'interfaccia.
* Piccole modifiche alla grafica.
* 20190125 - Aggiunta una frame i cui fare il tracciamento del mouse per mandare posizioni
* in tempo reale. La Z dovrebbbe essere compito della rotella del mouse che però
* non genera eventi, trovare una soluzione (magari con la tastiera) per sostituirla.
* L'invio dei comandi al robot dalla gui è TEMPORANEO, sarà gestito dal main
* per fare il calcolo della cinematica inversa.
* 20190128 - Sostituita la lettura della rotella con quella dei tasti freccia,
* rimane da risolvere il fatto che quando non si usa il mouse le coordinate impazziscono
* (ma è solo per test quindi va bene così forse)
* 20190131 - Piccole modifiche alla grafica, aggiunte visualizzazioni posizione giunti
* 20190211 - Scrittura delle funzioni che mandano i comandi parametrizzati al modulo roboglue_com
* per l'invio di istruzioni a ros tramite mqtt. L'invio diretto al modulo com è solo
* temporaneo, le comunicazioni andranno gestite tutte dal main.
* 20190308 - Riscrittura delle funzioni associate ai bottoni di Record e Play per includere i metadati del
* file da scrivere o leggere
* 20190311 - Inversione del segno coordinata y prima dell'invio al modulo com.
* 20190322 - Modifica dei nomi segnali tra questo modulo e com.
* 20190402 - Aggiunte due spinbox per il settaggio di delta tempo e delta spazio da salvare nel
* file dei metadati per la pianificazione dei persorsi salvati
*/
#include <QMainWindow>
#include <QString>
#include <QVariantMap>
#include <QJsonObject>
#include <QJsonDocument>
#include <QEvent>
#include <QMouseEvent>
#include <QFile>
#include <QUuid>
#include <QCoreApplication>
#include <boost/algorithm/clamp.hpp>
#include <libURcom/URCLinterface.h>
#include <shared/roboglue_shared.h>
namespace Ui {
class RoboGlue_GUI;
}
using nlohmann::json;
class RoboGlue_GUI : public QMainWindow {
Q_OBJECT
public:
explicit RoboGlue_GUI(RoboGlue_SHARED *mem = nullptr);
~RoboGlue_GUI();
private:
shared_ptr<spdlog::logger> modlog;
RoboGlue_SHARED *m;
Ui::RoboGlue_GUI *ui;
bool eventFilter(QObject* obj, QEvent* event);
json nameDefinitions;
QVariantMap getLockAxes(void);
void enableLockAxes(void);
void disableLockAxes(void);
public slots:
void on_commonStatusChange(void);
void on_newRobotData();
private slots:
void on_btn_sendCommand_clicked();
void on_btn_robotConnect_clicked();
void on_btn_robotDisconnect_clicked();
void on_chk_autoConnect_clicked(bool checked);
void on_pad_hoverEvent(QEvent *e);
void on_btn_record_clicked();
void on_btn_play_clicked();
void on_btn_realtime_clicked();
void on_btn_open_clicked();
signals:
void robotConnect(QString, uint port, uchar retry);
void robotDisconnect();
void robotSendURscript(QString);
void sendROScoordinates(QList<double>);
void sendROScommand(QString command, QVariantMap args);
void sendROSstate(QMap<std::string, bool> digital, QMap<std::string, uint16_t> analog);
void pad_hoverEvent(QEvent *e);
};
#endif // ROBOGLUE_GUI_H

1323
gui/roboglue_gui.ui Normal file

File diff suppressed because it is too large Load Diff

196
init/roboglue_init.cpp Normal file
View File

@@ -0,0 +1,196 @@
#include "roboglue_init.h"
#include "ui_roboglue_init.h"
RoboGlue_INIT::RoboGlue_INIT(QWidget *parent, const char*) : QMainWindow(parent) {
//////// SETUP LOGGER //////////
inilog = spdlog::stdout_logger_mt("RoboGlue_inilog");
inilog->info("INIT Started");
//////// SETUP USER INTERFACE ///////
ui = new Ui::RoboGlue_INIT;
ui->setupUi(this);
//////// INITIALIZE MEMORY MODULE ////////////
QCoreApplication::setOrganizationName("ETsoft");
QCoreApplication::setApplicationName("RoboGlue");
settings = new QSettings("../RoboGlue/roboglue.conf", QSettings::IniFormat);
sharedmem = new RoboGlue_SHARED(settings);
//////// RESTORE SETTINGS FOR ALL MODULES ////////////
sharedmem->restoreInitSettings();
sharedmem->restoreComSettings();
sharedmem->restoreGuiSettings();
sharedmem->restoreMainSettings();
sharedmem->restoreTrackSettings();
//////// RESTORE UI STATE ////////////
ui->chk_comAuto->setChecked(sharedmem->initSettings.autoCom);
ui->chk_guiAuto->setChecked(sharedmem->initSettings.autoGui);
ui->chk_mainAuto->setChecked(sharedmem->initSettings.autoMain);
ui->chk_trackAuto->setChecked(sharedmem->initSettings.autoTrack);
//////// AUTO START MODULES //////////
if (sharedmem->initSettings.autoGui) this->on_btn_guiStart_clicked();
if (sharedmem->initSettings.autoMain) this->on_btn_mainStart_clicked();
if (sharedmem->initSettings.autoCom) this->on_btn_comStart_clicked();
if (sharedmem->initSettings.autoTrack) this->on_btn_trackStart_clicked();
//////// CONNECT SIGNALS & SLOTS ///////
connect(this, SIGNAL(destroyed()), this, SLOT(deleteLater()), Qt::ConnectionType::QueuedConnection);
}
RoboGlue_INIT::~RoboGlue_INIT() {
// close order must be opposite of opening one
on_btn_trackStop_clicked();
on_btn_comStop_clicked();
on_btn_mainStop_clicked();
on_btn_guistop_clicked();
sharedmem->saveInitSettings();
sharedmem->saveMainSettings();
sharedmem->saveTrackSettings();
sharedmem->saveComSettings();
sharedmem->saveGuiSettings();
delete robot;
delete gui;
delete main;
delete track;
delete settings;
delete sharedmem;
delete ui;
}
///////////////////////////////////////////////////
/////////////// HEARTBEAT SLOTS ///////////////////
///////////////////////////////////////////////////
void RoboGlue_INIT::on_robotHeartBeat(){
}
void RoboGlue_INIT::on_guiHeartBeat(){
}
void RoboGlue_INIT::on_mainHeartBeat(){
}
void RoboGlue_INIT::on_trackHeartBeat(){
}
///////////////////////////////////////////////////
/////////////// BUTTON SLOTS //////////////////////
///////////////////////////////////////////////////
void RoboGlue_INIT::on_btn_comStart_clicked(){
if (robot == nullptr) {
robot = new RoboGlue_COM(sharedmem);
robot->start();
// connect signals
if (gui != nullptr){
// robot to gui
connect(robot, SIGNAL(com_newData(void)),
gui, SLOT(on_newRobotData(void)), Qt::ConnectionType::QueuedConnection);
//gui to robot
connect(gui, SIGNAL(sendROScommand(QString, QVariantMap)),
robot, SLOT(on_sendROScommand(QString,QVariantMap)),
Qt::ConnectionType::QueuedConnection);
connect(gui, SIGNAL(sendROScoordinates(QList<double>)),
robot, SLOT(on_sendROScoordinates(QList<double>)),
Qt::ConnectionType::QueuedConnection);
connect(gui, SIGNAL(sendROSstate(QMap<std::string, bool>, QMap<std::string, uint16_t>)),
robot, SLOT(on_sendROSstate(QMap<std::string, bool>, QMap<std::string, uint16_t>)),
Qt::ConnectionType::QueuedConnection);
connect(gui, SIGNAL(robotSendURscript(QString)),
robot, SLOT(on_sendURscript(QString)),
Qt::ConnectionType::QueuedConnection);
connect(gui, SIGNAL(robotConnect(QString, uint, uchar)),
robot, SLOT(on_connect(QString, uint, uchar)),
Qt::ConnectionType::QueuedConnection);
connect(gui, SIGNAL(robotDisconnect()),
robot, SLOT(on_disconnect()),
Qt::ConnectionType::QueuedConnection);
}
// robot to init
connect(robot, SIGNAL(com_heartBeat(void)),
this, SLOT(on_robotHeartBeat(void)), Qt::ConnectionType::QueuedConnection);
// shared memory to robot
connect(sharedmem, SIGNAL(commonStatusChange(void)),
robot, SLOT(on_commonStatusChange(void)));
}
}
void RoboGlue_INIT::on_btn_comStop_clicked() {
if (robot == nullptr) return;
robot->on_quit();
while (!robot->isFinished()){
QThread::msleep(100);
}
robot->deleteLater();
robot=nullptr;
}
void RoboGlue_INIT::on_btn_guiStart_clicked() {
if (gui == nullptr) {
gui = new RoboGlue_GUI(sharedmem);
gui->show();
// shared memory to robot
connect(sharedmem, SIGNAL(commonStatusChange(void)),
gui, SLOT(on_commonStatusChange(void)));
if (robot != nullptr){
}
}
}
void RoboGlue_INIT::on_btn_guistop_clicked() {
if (gui == nullptr) return;
gui->deleteLater();
gui = nullptr;
}
void RoboGlue_INIT::on_btn_mainStart_clicked() {
if (main == nullptr){
main = new RoboGlue_MAIN(sharedmem);
main->start();
// connect signals
// connect()
}
}
void RoboGlue_INIT::on_btn_mainStop_clicked(){
if (main == nullptr) return;
main->deleteLater();
main = nullptr;
}
void RoboGlue_INIT::on_btn_trackStart_clicked() {
if (track == nullptr){
track = new RoboGlue_TRACK(sharedmem);
track->start();
// connect signals
// connect()
}
}
void RoboGlue_INIT::on_btn_trackStop_clicked() {
if (track == nullptr) return;
track->deleteLater();
track = nullptr;
}
void RoboGlue_INIT::on_chk_comAuto_clicked(bool checked) {
sharedmem->initSettings.autoCom=checked;
}
void RoboGlue_INIT::on_chk_guiAuto_clicked(bool checked) {
sharedmem->initSettings.autoGui=checked;
}
void RoboGlue_INIT::on_chk_trackAuto_clicked(bool checked) {
sharedmem->initSettings.autoTrack=checked;
}
void RoboGlue_INIT::on_chk_mainAuto_clicked(bool checked){
sharedmem->initSettings.autoMain=checked;
}

61
init/roboglue_init.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef ROBOGLUE_INIT_H
#define ROBOGLUE_INIT_H
#include <QMainWindow>
#include <QThread>
#include <QSettings>
#include <spdlog/logger.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <shared/roboglue_shared.h>
#include <gui/roboglue_gui.h>
#include <com/roboglue_com.h>
#include <track/roboglue_track.h>
#include <main/roboglue_main.h>
namespace Ui {
class RoboGlue_INIT;
}
class RoboGlue_INIT : public QMainWindow
{
Q_OBJECT
public:
explicit RoboGlue_INIT(QWidget *parent = nullptr, const char* settingsFile = nullptr);
virtual ~RoboGlue_INIT();
private:
shared_ptr<spdlog::logger> inilog;
Ui::RoboGlue_INIT *ui;
QSettings *settings;
RoboGlue_SHARED *sharedmem;
RoboGlue_COM *robot = nullptr;
RoboGlue_GUI *gui = nullptr;
RoboGlue_MAIN *main = nullptr;
RoboGlue_TRACK *track = nullptr;
private slots:
// modules heartbeat slots
void on_robotHeartBeat();
void on_guiHeartBeat();
void on_mainHeartBeat();
void on_trackHeartBeat();
// button slots
void on_btn_comStart_clicked();
void on_btn_guiStart_clicked();
void on_btn_comStop_clicked();
void on_btn_guistop_clicked();
void on_btn_mainStart_clicked();
void on_btn_trackStart_clicked();
void on_btn_mainStop_clicked();
void on_btn_trackStop_clicked();
// checkbox slots
void on_chk_comAuto_clicked(bool checked);
void on_chk_guiAuto_clicked(bool checked);
void on_chk_trackAuto_clicked(bool checked);
void on_chk_mainAuto_clicked(bool checked);
};
#endif // ROBOGLUE_INIT_H

279
init/roboglue_init.ui Normal file
View File

@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RoboGlue_INIT</class>
<widget class="QMainWindow" name="RoboGlue_INIT">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>499</width>
<height>248</height>
</rect>
</property>
<property name="windowTitle">
<string>RoboGlue_INIT</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lbl_title">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:20pt;&quot;&gt;RoboGlue_INIT&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="3">
<widget class="QLabel" name="lbl_guiStatus">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="btn_comStop">
<property name="text">
<string>STOP</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Module</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QCheckBox" name="chk_mainAuto">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true">Auto</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="btn_guiStart">
<property name="text">
<string>START</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>RoboGlue_MAIN</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QCheckBox" name="chk_guiAuto">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>RoboGlue_GUI</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="lbl_mainStatus">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="btn_mainStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>START</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="btn_guistop">
<property name="text">
<string>STOP</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>RoboGlue_COM</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Status</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="btn_comStart">
<property name="text">
<string>START</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="btn_mainStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>STOP</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_7">
<property name="text">
<string>AutoStart</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QCheckBox" name="chk_comAuto">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="lbl_comStatus">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>RoboGlue_TRACK</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="btn_trackStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>START</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="btn_trackStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>STOP</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QCheckBox" name="chk_trackAuto">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="lbl_trackStatus">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

20406
libJson/json.hpp Normal file

File diff suppressed because it is too large Load Diff

258
libURcom/URCLinterface.cpp Normal file
View File

@@ -0,0 +1,258 @@
/*
* URCLinterface.cpp
*
* Created on: Jan 14, 2019
* Author: emanuele
*
* Implementazione C++ del protocollo di comunicazione socket per Universal Robot e-series.
* Protocollo client interface, comunicazione 10Hz su porte 30001 - 30002, informazioni e messaggi parziali,
* invio di comandi URscript
*
* 20190114 - Prima Scittura
* 20190114 - Inizio implementazione della connessione socket con libreria boost, scritta funzione connect.
* 20190115 - Continuo scirttura funzione dataRead(), verificato il protocollo rispetto al manuale, la funzione legge e divide corretamente i pacchetti
* tra di loro. ora bisogna separare i sottopacchetti.
* 20190116 - La separazione dei sottopacchetti viene fatta da delle classi specializzate che scompattano e cambiano
* l'endianness dei dati se necessario.
* 20190117 - Prima scirttura delle classi che scompattano i dati, scirtta versionMessage, risolti alcuni dubbi
* e problemi con i puntatori. A quanto pare non è disponibile una libreria che faccia quello che
* fa struct.unpack di python
* 20190118 - Completata la scrittura delle classi che scompattano i dati, le strutture combaciano con il
* manuale. Inizio della scrittura finzioni che mandano i comandi URscript al controller,
* valutare se vale la pena implementare per ogn tipo di funzione movimento
* prevista in URscript o no..
* 20190121 - Passaggio a nuova Vm con Ubuntu 18.04LTS e g++ 7.3.0, risolti alcuni problemi di compilazione,
* passaggio a librerie boost-1.68
* Scritta funzione di invio script grezzi al controller, inizio scrittura a thread che continua a ricevere
* i dati dal robot.
*/
#include "URCLinterface.h"
using namespace subpackage;
using namespace std;
using boost::format;
using std::string;
UR_CLinterface::UR_CLinterface(shared_ptr<spdlog::logger> logger) {
log = logger;
log->info("Initializing UR Client Interface"); // @suppress("Ambiguous problem")
rsocket = new tcp::socket(io_service);
}
UR_CLinterface::~UR_CLinterface() {
// TODO Auto-generated destructor stub
if (rsocket->is_open()) this->disconnect();
delete rsocket;
}
bool UR_CLinterface::connect(const char* ip, uint16_t port) {
try {
rsocket->connect(
tcp::endpoint(boost::asio::ip::address::from_string(ip), port));
if ((bool) rsocket->is_open()) {
log->info("Connected to {0} on port {1}", ip, port);
return true;
}
} catch (boost::system::error_code* e) {
log->error(e->message());
return false;
}
return false;
}
void UR_CLinterface::disconnect(void) {
rsocket->close(error);
if (error){
log->error("Cannot close socket, code: {}", error.message()); // @suppress("Assignment in condition")
return;
}
log->info("Disconnected"); // @suppress("Ambiguous problem")
}
void UR_CLinterface::sendCommand(std::string command) {
char* dataOut=NULL;
if (rsocket->is_open()){
command = command + '\n';
dataOut = (char*)malloc(command.size());
strncpy(dataOut, command.c_str(), command.size());
log->debug("Sending: {}, s:{}",dataOut,command.size());
boost::asio::write(*rsocket, boost::asio::buffer(dataOut, command.size()), error);
free(dataOut);
}
if (!error) return;
else {
log->error("Failed to send data to socket, code: {}", error.message());
}
}
void UR_CLinterface::parseData(void){
uint32_t packageSize=lastDataLen;
uint32_t subPackageSize;
unsigned char packageType;
unsigned char subPackageType;
uint32_t currIndex=0;
clientSubpackage* subP=NULL;
//main message type is on 4th byte of the message
packageType = lastData[sizeof(uint32_t)];
switch(packageType){
case VERSION_MESSAGE: //begin version message parse
if (firstMessage){
log->info("Version Message: size[{}]",packageSize); // @suppress("Ambiguous problem")
subP = new versionSub(lastData, &clientData);
subP->parse();
firstMessage=false;
long t=(long)clientData.versonMessage.timestamp;
std::string timestr=std::string(asctime(gmtime(&t)));
timestr.pop_back();
log->info("Connection Time: {}", timestr);
log->info("Controller Version {0}.{1}", clientData.versonMessage.majorVersion,
clientData.versonMessage.minorVersion);
log->info("ProjectName: {}", clientData.versonMessage.projectName->c_str());
}
break;
case ROBOT_MESSAGE: // begin subpacket parse
// move index to skip package leader
currIndex = sizeof(uint32_t)+sizeof(char);
log->debug("Robot Message: size[{}]",packageSize);
// iterate until end of package
while (currIndex < lastDataLen){
// free memory
if (subP != NULL) {
delete subP;
subP = NULL;
}
//extract subpackage size
memcpy(&subPackageSize, lastData+currIndex, sizeof(uint32_t));
subPackageSize=big_to_native(subPackageSize);
// extract subpackage type
subPackageType=lastData[currIndex+sizeof(uint32_t)];
try{
switch (subPackageType){
case ROBOT_MODE_DATA:
log->debug("SubP_ModeData"); // @suppress("Ambiguous problem")
subP = new robotModeSub(&lastData[currIndex], &clientData);
break;
case JOINT_DATA:
log->debug("SubP_JointData"); // @suppress("Ambiguous problem")
subP = new jointDataSub(&lastData[currIndex], &clientData);
break;
case TOOL_DATA:
log->debug("SubP_ToolData"); // @suppress("Ambiguous problem")
subP = new toolDataSub(&lastData[currIndex], &clientData);
break;
case MASTER_BOARD_DATA:
log->debug("SubP_MasterBoardData"); // @suppress("Ambiguous problem")
subP = new masterBoardSub(&lastData[currIndex], &clientData);
break;
case CARTESIAN_INFO:
log->debug("SubP_CartesianInfo"); // @suppress("Ambiguous problem")
subP = new cartesianInfoSub(&lastData[currIndex], &clientData);
break;
case KINEMATICS_INFO:
log->debug("SubP_KinematicsInfo"); // @suppress("Ambiguous problem")
subP = new kineInfoSub(&lastData[currIndex], &clientData);
break;
case CONFIGURATION_DATA:
log->debug("SubP_ConfigurationData"); // @suppress("Ambiguous problem")
subP = new configurationSub(&lastData[currIndex], &clientData);
break;
case FORCE_MODE_DATA:
log->debug("SubP_ForceModeData"); // @suppress("Ambiguous problem")
subP = new forceModeSub(&lastData[currIndex], &clientData);
break;
case ADDITIONAL_INFO:
log->debug("SubP_AdditionalInfo"); // @suppress("Ambiguous problem")
subP = new additionalInfoSub(&lastData[currIndex], &clientData);
break;
case CALIBRATION_DATA:
log->debug("SubP_CalibrationData"); // @suppress("Ambiguous problem")
subP = new calibrationSub(&lastData[currIndex], &clientData);
break;
case TOOL_COM_INFO:
log->debug("SubP_ToolComInfo"); // @suppress("Ambiguous problem")
subP = new toolComSub(&lastData[currIndex], &clientData);
break;
case TOOL_MODE_INFO:
log->debug("SubP_ToolModeInfo"); // @suppress("Ambiguous problem")
subP = new toolModeSub(&lastData[currIndex], &clientData);
break;
case SAFETY_DATA:
//not yet implemented
break;
default:
log->error("Unknown Subpackage: {}", subPackageType);
break;
}
if (subP != NULL) subP->parse();
currIndex+=subPackageSize;
} catch (long sizediff){
log->error("Package Length Mismatch: {}",sizediff);
currIndex+=subPackageSize;
}
}
log->debug("End of Package"); // @suppress("Ambiguous problem")
break;
default:
log->error("Unknown package type: {}",packageType);
break;
}
clientData.lastUpdate = time(NULL);
}
void UR_CLinterface::readData(void) {
uint32_t packlen;
uint32_t readata = 0;
string rawdata;
if (rsocket->is_open()){
// clear last data vector
if(lastData!=NULL)
free(lastData);
//read first incoming byte for packet length
boost::asio::read(*rsocket, receive_buffer, boost::asio::transfer_exactly(HEADERSIZE), error);
if (!error) {
const unsigned char* f = boost::asio::buffer_cast<const unsigned char*>(receive_buffer.data());
memcpy(&packlen, f, HEADERSIZE * sizeof(char));
// all number are represented in network byte order, conversion required
packlen = ntohl(packlen);
// allocate memory for incoming package
lastData = (unsigned char*)malloc(packlen);
// blocking read of exactly packlen bytes
readata += boost::asio::read(*rsocket, receive_buffer,boost::asio::transfer_exactly(packlen), error);
//retreive all data from buffer
const unsigned char* ff = boost::asio::buffer_cast<const unsigned char*>(receive_buffer.data());
// flush buffer for reuse
receive_buffer.consume(packlen);
// print packet dump
log->debug("Successful read: {0} bytes", readata);
if (log->level() == spdlog::level::trace) {
char hh[5];
for (uint32_t k = 0; k < packlen; k++) {
sprintf(hh, "%02x|", ff[k]);
rawdata.append(hh);
if (k % 16 == 0 && k != 0)
rawdata.append("\n");
}
log->trace("\n{}\n", rawdata);
}
//export data to vector
memcpy(lastData, ff, packlen);
lastDataLen=packlen;
} else {
log->error("Failed to read data from socket, code: {}", error.message());
}
} else {
log->error("Robot not connected!, call connect(ip,port) instead"); // @suppress("Ambiguous problem")
}
}

54
libURcom/URCLinterface.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* URCLinterface.h
*
* Created on: Jan 14, 2019
* Author: emanuele
*/
#ifndef URCLINTERFACE_H_
#define URCLINTERFACE_H_
#include "clientMessage.h"
#include <ctime>
#include <iostream>
#include <arpa/inet.h>
#include <spdlog/spdlog.h>
#include <boost/asio.hpp>
#include <boost/format.hpp>
using namespace std;
using namespace boost::asio;
using ip::tcp;
class UR_CLinterface {
public:
UR_CLinterface(shared_ptr<spdlog::logger>);
virtual ~UR_CLinterface();
bool connect(const char* ip, uint16_t port);
void disconnect();
void sendCommand(std::string command);
void sendPose(pose_t pos);
void sendJointPose(jointPose_t pos);
void readData();
void parseData();
clientData_t clientData;
private:
shared_ptr<spdlog::logger> log;
boost::asio::io_service io_service;
boost::asio::streambuf receive_buffer;
boost::system::error_code error;
tcp::socket* rsocket;
uint32_t lastDataLen=0;
unsigned char* lastData=NULL;
bool firstMessage=true;
};
#endif /* URCLINTERFACE_H_ */

455
libURcom/clientMessage.cpp Normal file
View File

@@ -0,0 +1,455 @@
/*
* clientMessage.cpp
*
* Created on: Jan 16, 2019
* Author: emanuele
*/
#include "clientMessage.h"
namespace subpackage {
clientSubpackage::clientSubpackage() {
}
clientSubpackage::~clientSubpackage() {
}
uint32_t clientSubpackage::parse() {
return 0;
}
versionSub::~versionSub() {
}
configurationSub::~configurationSub() {
}
calibrationSub::~calibrationSub() {
}
robotModeSub::~robotModeSub() {
}
forceModeSub::~forceModeSub() {
}
kineInfoSub::~kineInfoSub() {
}
jointDataSub::~jointDataSub() {
}
cartesianInfoSub::~cartesianInfoSub() {
}
additionalInfoSub::~additionalInfoSub() {
}
toolDataSub::~toolDataSub() {
}
toolModeSub::~toolModeSub() {
}
toolComSub::~toolComSub() {
}
masterBoardSub::~masterBoardSub() {
}
uint32_t subpackage::clientSubpackage::getUInt32(unsigned char** dataPointer) {
uint32_t d;
memcpy(&d, *dataPointer, sizeof(uint32_t));
*dataPointer+=sizeof(uint32_t);
return big_to_native(d);
}
uint64_t subpackage::clientSubpackage::getUInt64(unsigned char** dataPointer) {
uint64_t d;
memcpy(&d, *dataPointer, sizeof(uint64_t));
*dataPointer+=sizeof(uint64_t);
return big_to_native(d);
}
int32_t subpackage::clientSubpackage::getInt32(unsigned char** dataPointer) {
int32_t d;
memcpy(&d, *dataPointer, sizeof(int32_t));
*dataPointer+=sizeof(int32_t);
return big_to_native(d);
}
double subpackage::clientSubpackage::getDouble(unsigned char** dataPointer) {
union{
uint64_t i;
double dd;
} d;
memcpy(&d, *dataPointer, sizeof(double));
d.i=big_to_native(d.i);
*dataPointer+=sizeof(double);
return d.dd;
}
float subpackage::clientSubpackage::getFloat(unsigned char** dataPointer) {
union{
uint32_t i;
float dd;
} d;
memcpy(&d, *dataPointer, sizeof(float));
d.i=big_to_native(d.i);
*dataPointer+=sizeof(float);
return d.dd;
}
char subpackage::clientSubpackage::getChar(unsigned char** dataPointer) {
char val=**dataPointer;
*dataPointer+=1;
return val;
}
unsigned char subpackage::clientSubpackage::getUChar(unsigned char** dataPointer) {
unsigned char val=**dataPointer;
*dataPointer+=1;
return val;
}
void clientSubpackage::copyString(std::string **out, unsigned char** in, char len) {
char* s=NULL;
if (*out != NULL)
delete(out);
s = (char*)malloc(len+1);
strncpy(s, (const char*)*in, len);
s[(unsigned char)len]='\0';
*out = new std::string(s);
free(s);
*in+=len;
}
//////////////////////////////////////////////////////////////////////////////
/////////////// Overload of Parse Method /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
uint32_t subpackage::robotModeSub::parse() {
robotModeData_t *v = &dataOut->robotMode;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->timestamp = this->getUInt64(&dataIn);
v->isRealRobotConnected = this->getUChar(&dataIn);
v->isRealRobotEnabled = this->getUChar(&dataIn);
v->isRobotPowerOn = this->getUChar(&dataIn);
v->isEmergencyStopped = this->getUChar(&dataIn);
v->isProtectiveStopped = this->getUChar(&dataIn);
v->isProgramRunning = this->getUChar(&dataIn);
v->isProgramPaused = this->getUChar(&dataIn);
v->robotMode = this->getUChar(&dataIn);
v->controlMode = this->getUChar(&dataIn);
v->targetSpeedFraction = this->getDouble(&dataIn);
v->speedScaling = this->getDouble(&dataIn);
v->targetSpeedFractionLimit = this->getDouble(&dataIn);
v->internalValue = this->getUChar(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::jointDataSub::parse() {
jointData_t *v = &dataOut->jointData;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for (c=0; c<JOINT_NUMBER; c++){
v->jointParam[c].actual = this->getDouble(&dataIn);
v->jointParam[c].target = this->getDouble(&dataIn);
v->jointParam[c].speedActual = this->getDouble(&dataIn);
v->jointParam[c].current = this->getFloat(&dataIn);
v->jointParam[c].voltage = this->getFloat(&dataIn);
v->jointParam[c].motorTemp = this->getFloat(&dataIn);
v->jointParam[c].nc = this->getFloat(&dataIn);
v->jointParam[c].mode = this->getUChar(&dataIn);
}
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::cartesianInfoSub::parse() {
cartesianInfo_t *v = &dataOut->cartesianInfo;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for (c=0; c<JOINT_NUMBER; c++){
v->cartPosition.pos[c] = this->getDouble(&dataIn);
}
for (c=0; c<JOINT_NUMBER; c++){
v->cartTCPoffset.ofst[c] = this->getDouble(&dataIn);
}
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::masterBoardSub::parse() {
masterBoardData_t *v = &dataOut->masterBoard;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->digitalInputBits = this->getUInt32(&dataIn);
v->digitalOutputBits = this->getUInt32(&dataIn);
v->analogInputRange0 = this->getUChar(&dataIn);
v->analogInputRange1 = this->getUChar(&dataIn);
v->analogInput0 = this->getDouble(&dataIn);
v->analogInput1 = this->getDouble(&dataIn);
v->analogOutputDomain0 = this->getChar(&dataIn);
v->analogOutputDomain1 = this->getChar(&dataIn);
v->analogOutput0 = this->getDouble(&dataIn);
v->analogOutput1 = this->getDouble(&dataIn);
v->masterBoardTemperature = this->getFloat(&dataIn);
v->robotVoltage48V = this->getFloat(&dataIn);
v->robotCurrent = this->getFloat(&dataIn);
v->masterIOCurrent = this->getFloat(&dataIn);
v->safetyMode = this->getUChar(&dataIn);
v->InReducedMode = this->getUChar(&dataIn);
v->euromap67InterfaceInstalled = this->getChar(&dataIn);
#ifdef EUROMAP
v->euromapInputBits = this->getUInt32(&dataIn);
v->euromapOutputBits = this->getUInt32(&dataIn);
v->euromapVoltage24V = this->getFloat(&dataIn);
v->euromapCurrent = this->getFloat(&dataIn);
#endif
v->nc = this->getUInt32(&dataIn);
v->operationalModeSelectorInput = this->getUChar(&dataIn);
v->threePositionEnblingDeviceInput = this->getUChar(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::toolDataSub::parse() {
toolData_t *v = &dataOut->toolData;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->analogInputRange0 = this->getUChar(&dataIn);
v->analogInputRange1 = this->getUChar(&dataIn);
v->analogInput0 = this->getDouble(&dataIn);
v->analogInput1 = this->getDouble(&dataIn);
v->toolVoltage48V = this->getFloat(&dataIn);
v->toolOutputVoltage = this->getUChar(&dataIn);
v->toolCurrent = this->getFloat(&dataIn);
v->toolTemperature = this->getFloat(&dataIn);
v->toolMode = this->getUChar(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::kineInfoSub::parse() {
kinematicsInfo_t *v = &dataOut->kineInfo;
kineDH_t *k=&dataOut->kineInfo.kinematics;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for(c=0; c<JOINT_NUMBER; c++){
v->checksum[c]=this->getUInt32(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHtheta[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHa[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHd[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHalpha[c]=this->getDouble(&dataIn);
}
v->calibration_status = this->getUInt32(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::configurationSub::parse() {
configurationData_t *v = &dataOut->configuration;
kineDH_t *k=&dataOut->configuration.kinematics;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for(c=0; c<JOINT_NUMBER; c++){
v->jointPositionLimits[c].min=this->getDouble(&dataIn);
v->jointPositionLimits[c].max=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
v->jointSpeedLimits[c].min=this->getDouble(&dataIn);
v->jointSpeedLimits[c].max=this->getDouble(&dataIn);
}
v->vJointDefault=this->getDouble(&dataIn);
v->aJointDefault=this->getDouble(&dataIn);
v->vToolDefault=this->getDouble(&dataIn);
v->aToolDefault=this->getDouble(&dataIn);
v->eqRadius=this->getDouble(&dataIn);
for(c=0; c<JOINT_NUMBER; c++){
k->DHa[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHd[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHalpha[c]=this->getDouble(&dataIn);
}
for(c=0; c<JOINT_NUMBER; c++){
k->DHtheta[c]=this->getDouble(&dataIn);
}
v->masterboardVersion=this->getUInt32(&dataIn);
v->controllerBoxType=this->getInt32(&dataIn);
v->robotType=this->getInt32(&dataIn);
v->robotSubType=this->getInt32(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::forceModeSub::parse() {
forceModeData_t *v = &dataOut->forceMode;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for(c=0; c<JOINT_NUMBER; c++){
v->forcePosition.force[c] = this->getDouble(&dataIn);
}
v->robotDexterity = this->getDouble(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::additionalInfoSub::parse() {
additionalInfo_t *v = &dataOut->additionalInfo;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->feedriveButtonPressed = this->getUChar(&dataIn);
v->feedriveButtonEnabled = this->getUChar(&dataIn);
v->ioEnableFeedrive = this->getUChar(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::calibrationSub::parse() {
calibrationData_t *v = &dataOut->calibrationData;
unsigned char* begin = dataIn;
uint32_t size;
uint32_t c;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
for(c=0; c<JOINT_NUMBER; c++){
v->fcalData.force[c] = this->getDouble(&dataIn);
}
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::toolComSub::parse() {
toolCommunicationInfo_t *v = &dataOut->toolCom;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->communicationIsEnabled = this->getUChar(&dataIn);
v->baudRate = this->getInt32(&dataIn);
v->parity = this->getInt32(&dataIn);
v->stopBits = this->getInt32(&dataIn);
v->rxIdleChars = this->getFloat(&dataIn);
v->txIdleChars = this->getFloat(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::toolModeSub::parse() {
toolModeInfo_t *v = &dataOut->toolMode;
unsigned char* begin = dataIn;
uint32_t size;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->outputMode = this->getChar(&dataIn);
v->digitalModeOut0 = this->getUChar(&dataIn);
v->digitalModeOut1 = this->getUChar(&dataIn);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
uint32_t subpackage::versionSub::parse() {
versionMessage_t *v = &dataOut->versonMessage;
unsigned char* begin = dataIn;
uint32_t size;
char nameSize;
size = v->packageSize = this->getInt32(&dataIn);
v->packageType = this->getUChar(&dataIn);
v->timestamp = this->getUInt64(&dataIn);
v->source = this->getChar(&dataIn);
v->robotMessageType = this->getChar(&dataIn);
nameSize = v->projectNameSize = this->getChar(&dataIn);
this->copyString(&v->projectName, &dataIn, nameSize);
v->majorVersion = this->getUChar(&dataIn);
v->minorVersion = this->getUChar(&dataIn);
v->bugFixVersion = this->getUChar(&dataIn);
v->buildNumber = this->getUChar(&dataIn);
nameSize = (begin+v->packageSize-dataIn);
this->copyString(&v->buildDate, &dataIn, nameSize);
// check if read data is aligned with package size
if (dataIn-begin != size) throw dataIn-begin-size;
return dataIn-begin;
}
} /* namespace clientmessage */

182
libURcom/clientMessage.h Normal file
View File

@@ -0,0 +1,182 @@
/*
* clientMessage.h
*
* Created on: Jan 16, 2019
* Author: emanuele
*/
#ifndef CLIENTMESSAGE_H_
#define CLIENTMESSAGE_H_
#include "packagetypes.h"
#include <string>
#include <arpa/inet.h>
#include <boost/endian/conversion.hpp>
namespace subpackage {
class clientSubpackage {
public:
clientSubpackage();
virtual ~clientSubpackage();
unsigned char* dataIn;
clientData_t* dataOut;
virtual uint32_t parse();
void copyString(std::string** out, unsigned char** in, char len);
uint32_t getUInt32(unsigned char** dataPointer);
uint64_t getUInt64(unsigned char** dataPointer);
int32_t getInt32(unsigned char** dataPointer);
double getDouble(unsigned char** dataPointer);
float getFloat(unsigned char** dataPointer);
char getChar(unsigned char** dataPointer);
unsigned char getUChar(unsigned char** dataPointer);
};
class robotModeSub: public clientSubpackage {
public:
robotModeSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~robotModeSub();
uint32_t parse();
};
class jointDataSub: public clientSubpackage {
public:
jointDataSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~jointDataSub();
uint32_t parse();
};
class cartesianInfoSub: public clientSubpackage {
public:
cartesianInfoSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~cartesianInfoSub();
uint32_t parse();
};
class masterBoardSub: public clientSubpackage {
public:
masterBoardSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~masterBoardSub();
uint32_t parse();
};
class toolDataSub: public clientSubpackage {
public:
toolDataSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~toolDataSub();
uint32_t parse();
};
class kineInfoSub: public clientSubpackage {
public:
kineInfoSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~kineInfoSub();
uint32_t parse();
};
class configurationSub: public clientSubpackage {
public:
configurationSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~configurationSub();
uint32_t parse();
};
class forceModeSub: public clientSubpackage {
public:
forceModeSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~forceModeSub();
uint32_t parse();
};
class additionalInfoSub: public clientSubpackage {
public:
additionalInfoSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~additionalInfoSub();
uint32_t parse();
};
class calibrationSub: public clientSubpackage {
public:
calibrationSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~calibrationSub();
uint32_t parse();
};
class toolComSub: public clientSubpackage {
public:
toolComSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~toolComSub();
uint32_t parse();
};
class toolModeSub: public clientSubpackage {
public:
toolModeSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout;
};
virtual ~toolModeSub();
uint32_t parse();
};
class versionSub: public clientSubpackage {
public:
versionSub(unsigned char* din, clientData_t* dout) {
dataIn=din;
dataOut=dout; };
virtual ~versionSub();
uint32_t parse();
};
} /* namespace clientmessage */
#endif /* CLIENTMESSAGE_H_ */

349
libURcom/packagetypes.h Normal file
View File

@@ -0,0 +1,349 @@
/*
* packagetypes.h
*
* Created on: Jan 14, 2019
* Author: emanuele
*
* Strutture e definizioni dei pacchetti utilizzati dal protocollo Client Interface di UR
*
*/
#include <cstdint>
#include <ctime>
#include <boost/endian/buffers.hpp>
using namespace boost::endian;
#define HEADERSIZE 4
//#define EUROMAP
#define JOINT_NUMBER 6
// PACKET TYPES
#define VERSION_MESSAGE 20
#define ROBOT_MESSAGE 16
// SUBPACKET TYPES
#define ROBOT_MODE_DATA 0
#define JOINT_DATA 1
#define TOOL_DATA 2
#define MASTER_BOARD_DATA 3
#define CARTESIAN_INFO 4
#define KINEMATICS_INFO 5
#define CONFIGURATION_DATA 6
#define FORCE_MODE_DATA 7
#define ADDITIONAL_INFO 8
#define CALIBRATION_DATA 9
#define SAFETY_DATA 10
#define TOOL_COM_INFO 11
#define TOOL_MODE_INFO 12
enum {
ROBOT_MODE_NO_CONTROLLER = -1,
ROBOT_MODE_DISCONNECTED,
ROBOT_MODE_CONFIRM_SAFETY,
ROBOT_MODE_BOOTING,
ROBOT_MODE_POWER_OFF,
ROBOT_MODE_POWER_ON,
ROBOT_MODE_IDLE,
ROBOT_MODE_BACKDRIVE,
ROBOT_MODE_RUNNING,
ROBOT_MODE_UPDATING_FIRMWARE,
} robotModes;
enum {
CONTROL_MODE_POSITION = 0,
CONTROL_MODE_TEACH,
CONTROL_MODE_FORCE,
CONTROL_MODE_TORQUE,
} controlModes;
enum {
JOINT_MODE_RESET =235,
JOINT_MODE_SHUTTING_DOWN,
JOINT_PART_D_CALIBRATION_MODE,
JOINT_MODE_BACKDRIVE,
JOINT_MODE_POWER_OFF,
JOINT_MODE_READY_FOR_POWER_OFF,
JOINT_MODE_NOT_RESPONDING,
JOINT_MODE_MOTOR_INITIALISATION,
JOINT_MODE_BOOTING,
JOINT_PART_D_CALIBRATION_ERROR_MODE,
JOINT_MODE_BOOTLOADER,
JOINT_CALIBRATION_MODE,
JOINT_MODE_VIOLATION,
JOINT_MODE_FAULT,
JOINT_MODE_RUNNING,
JOINT_MODE_IDLE
} jointModes;
enum {
SAFETY_MODE_NORMAL = 1,
SAFETY_MODE_REDUCED,
SAFETY_MODE_PROTECTIVE_STOP,
SAFETY_MODE_RECOVERY,
SAFETY_MODE_SAFEGUARD_STOP,
SAFETY_MODE_SYSTEM_EMERGENCY_STOP,
SAFETY_MODE_ROBOT_EMERGENCY_STOP,
SAFETY_MODE_VIOLATION,
SAFETY_MODE_FAULT,
SAFETY_MODE_VALIDATE_JOINT_ID,
SAFETY_MODE_UNDEFINED_SAFETY_MODE
} safetyModes;
typedef struct {
int32_t packageSize;
unsigned char packageType;
uint64_t timestamp;
char source;
char robotMessageType;
char projectNameSize;
std::string *projectName=NULL;
unsigned char majorVersion;
unsigned char minorVersion;
unsigned char bugFixVersion;
unsigned char buildNumber;
std::string *buildDate=NULL;
} versionMessage_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
int64_t timestamp;
unsigned char isRealRobotConnected;
unsigned char isRealRobotEnabled;
unsigned char isRobotPowerOn;
unsigned char isEmergencyStopped;
unsigned char isProtectiveStopped;
unsigned char isProgramRunning;
unsigned char isProgramPaused;
unsigned char robotMode;
unsigned char controlMode;
double targetSpeedFraction;
double speedScaling;
double targetSpeedFractionLimit;
unsigned char internalValue;
} robotModeData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
struct {
double actual;
double target;
double speedActual;
float current;
float voltage;
float motorTemp;
float nc;
unsigned char mode;
} jointParam [JOINT_NUMBER];
} jointData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
union {
struct{
double X;
double Y;
double Z;
double RX;
double RY;
double RZ;
};
double pos [6];
} cartPosition;
union {
struct{
double ofstX;
double ofstY;
double ofstZ;
double ofstRX;
double ofstRY;
double ofstRZ;
};
double ofst [6];
} cartTCPoffset;
} cartesianInfo_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
uint32_t digitalInputBits;
uint32_t digitalOutputBits;
unsigned char analogInputRange0;
unsigned char analogInputRange1;
double analogInput0;
double analogInput1;
char analogOutputDomain0;
char analogOutputDomain1;
double analogOutput0;
double analogOutput1;
float masterBoardTemperature;
float robotVoltage48V;
float robotCurrent;
float masterIOCurrent;
unsigned char safetyMode;
unsigned char InReducedMode;
char euromap67InterfaceInstalled;
#ifdef EUROMAP
uint32_t euromapInputBits;
uint32_t euromapOutputBits;
float euromapVoltage24V;
float euromapCurrent;
#endif
uint32_t nc;
unsigned char operationalModeSelectorInput;
unsigned char threePositionEnblingDeviceInput;
} masterBoardData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
unsigned char analogInputRange0;
unsigned char analogInputRange1;
double analogInput0;
double analogInput1;
float toolVoltage48V;
unsigned char toolOutputVoltage;
float toolCurrent;
float toolTemperature;
unsigned char toolMode;
} toolData_t;
typedef struct {
double DHa [JOINT_NUMBER];
double DHd [JOINT_NUMBER];
double DHalpha [JOINT_NUMBER];
double DHtheta [JOINT_NUMBER];
} kineDH_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
uint32_t checksum [JOINT_NUMBER];
kineDH_t kinematics;
unsigned char calibration_status;
} kinematicsInfo_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
struct {
double min;
double max;
} jointPositionLimits [JOINT_NUMBER];
struct {
double min;
double max;
} jointSpeedLimits [JOINT_NUMBER];
double vJointDefault;
double aJointDefault;
double vToolDefault;
double aToolDefault;
double eqRadius;
kineDH_t kinematics;
int32_t masterboardVersion;
int32_t controllerBoxType;
int32_t robotType;
int32_t robotSubType;
} configurationData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
union {
struct{
double FX;
double FY;
double FZ;
double FRX;
double FRY;
double FRZ;
};
double force[6];
} forcePosition;
double robotDexterity;
} forceModeData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
unsigned char feedriveButtonPressed;
unsigned char feedriveButtonEnabled;
unsigned char ioEnableFeedrive;
} additionalInfo_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
union {
struct{
double FX;
double FY;
double FZ;
double FRX;
double FRY;
double FRZ;
};
double force[6];
} fcalData;
} calibrationData_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
unsigned char communicationIsEnabled;
int32_t baudRate;
int32_t parity;
int32_t stopBits;
float rxIdleChars;
float txIdleChars;
} toolCommunicationInfo_t;
typedef struct {
int32_t packageSize;
unsigned char packageType;
unsigned char outputMode;
unsigned char digitalModeOut0;
unsigned char digitalModeOut1;
} toolModeInfo_t;
typedef struct {
versionMessage_t versonMessage;
configurationData_t configuration;
calibrationData_t calibrationData;
robotModeData_t robotMode;
forceModeData_t forceMode;
kinematicsInfo_t kineInfo;
jointData_t jointData;
cartesianInfo_t cartesianInfo;
additionalInfo_t additionalInfo;
toolData_t toolData;
toolModeInfo_t toolMode;
toolCommunicationInfo_t toolCom;
masterBoardData_t masterBoard;
time_t lastUpdate;
} clientData_t;
typedef struct {
union{
struct {
double X,Y,Z,RX,RY,RZ;
};
double p[JOINT_NUMBER];
};
} pose_t;
typedef struct {
union{
struct {
double J1,J2,J3,J4,J5,J6;
};
double p[JOINT_NUMBER];
};
} jointPose_t;

View File

@@ -0,0 +1,4 @@
((nil . ((indent-tabs-mode . nil)
(c-basic-offset . 4)
(fill-column . 80))))

46
libmodbus-master/.gitignore vendored Normal file
View File

@@ -0,0 +1,46 @@
*~
*.swp
*.o
*.la
*.lo
*.log
*.trs
.deps
.libs
GPATH
GRTAGS
GSYMS
GTAGS
INSTALL
Makefile
Makefile.in
/aclocal.m4
/autom4te.cache
/build-aux
/config.*
/configure
/configure.scan
/depcomp
/install-sh
/libtool
/ltmain.sh
/missing
/libmodbus.pc
/stamp-h1
/*.sublime-*
/.vscode
src/modbus-version.h
src/win32/modbus.dll.manifest
tests/bandwidth-client
tests/bandwidth-server-many-up
tests/bandwidth-server-one
tests/random-test-client
tests/random-test-server
tests/unit-test-client
tests/unit-test.h
tests/unit-test-server
tests/version
tests/stamp-h2
doc/*.html
doc/*.3
doc/*.7

View File

@@ -0,0 +1,7 @@
language: c
compiler:
- gcc
- clang
script: ./autogen.sh && ./configure && make && make check

View File

@@ -0,0 +1,42 @@
EXTRA_DIST =
lib_LTLIBRARIES = libmodbus.la
AM_CPPFLAGS = \
-include $(top_builddir)/config.h \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DLIBEXECDIR=\""$(libexecdir)"\" \
-I${top_srcdir}/src
AM_CFLAGS = ${my_CFLAGS}
libmodbus_la_SOURCES = \
modbus.c \
modbus.h \
modbus-data.c \
modbus-private.h \
modbus-rtu.c \
modbus-rtu.h \
modbus-rtu-private.h \
modbus-tcp.c \
modbus-tcp.h \
modbus-tcp-private.h \
modbus-version.h
libmodbus_la_LDFLAGS = -no-undefined \
-version-info $(LIBMODBUS_LT_VERSION_INFO)
if OS_WIN32
libmodbus_la_LIBADD = -lwsock32
endif
if OS_QNX
libmodbus_la_LIBADD = -lsocket
endif
# Header files to install
libmodbusincludedir = $(includedir)/modbus
libmodbusinclude_HEADERS = modbus.h modbus-version.h modbus-rtu.h modbus-tcp.h
DISTCLEANFILES = modbus-version.h
EXTRA_DIST += modbus-version.h.in
CLEANFILES = *~

View File

@@ -0,0 +1,233 @@
/*
* Copyright © 2010-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include <stdlib.h>
#ifndef _MSC_VER
# include <stdint.h>
#else
# include "stdint.h"
#endif
#include <string.h>
#include <assert.h>
#if defined(_WIN32)
# include <winsock2.h>
#else
# include <arpa/inet.h>
#endif
#include <config.h>
#include "modbus.h"
#if defined(HAVE_BYTESWAP_H)
# include <byteswap.h>
#endif
#if defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define bswap_16 OSSwapInt16
# define bswap_32 OSSwapInt32
# define bswap_64 OSSwapInt64
#endif
#if defined(__GNUC__)
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
# if GCC_VERSION >= 430
// Since GCC >= 4.30, GCC provides __builtin_bswapXX() alternatives so we switch to them
# undef bswap_32
# define bswap_32 __builtin_bswap32
# endif
# if GCC_VERSION >= 480
# undef bswap_16
# define bswap_16 __builtin_bswap16
# endif
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
# define bswap_32 _byteswap_ulong
# define bswap_16 _byteswap_ushort
#endif
#if !defined(bswap_16)
# warning "Fallback on C functions for bswap_16"
static inline uint16_t bswap_16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif
#if !defined(bswap_32)
# warning "Fallback on C functions for bswap_32"
static inline uint32_t bswap_32(uint32_t x)
{
return (bswap_16(x & 0xffff) << 16) | (bswap_16(x >> 16));
}
#endif
/* Sets many bits from a single byte value (all 8 bits of the byte value are
set) */
void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value)
{
int i;
for (i=0; i < 8; i++) {
dest[idx+i] = (value & (1 << i)) ? 1 : 0;
}
}
/* Sets many bits from a table of bytes (only the bits between idx and
idx + nb_bits are set) */
void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits,
const uint8_t *tab_byte)
{
unsigned int i;
int shift = 0;
for (i = idx; i < idx + nb_bits; i++) {
dest[i] = tab_byte[(i - idx) / 8] & (1 << shift) ? 1 : 0;
/* gcc doesn't like: shift = (++shift) % 8; */
shift++;
shift %= 8;
}
}
/* Gets the byte value from many bits.
To obtain a full byte, set nb_bits to 8. */
uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx,
unsigned int nb_bits)
{
unsigned int i;
uint8_t value = 0;
if (nb_bits > 8) {
/* Assert is ignored if NDEBUG is set */
assert(nb_bits < 8);
nb_bits = 8;
}
for (i=0; i < nb_bits; i++) {
value |= (src[idx+i] << i);
}
return value;
}
/* Get a float from 4 bytes (Modbus) without any conversion (ABCD) */
float modbus_get_float_abcd(const uint16_t *src)
{
float f;
uint32_t i;
i = ntohl(((uint32_t)src[0] << 16) + src[1]);
memcpy(&f, &i, sizeof(float));
return f;
}
/* Get a float from 4 bytes (Modbus) in inversed format (DCBA) */
float modbus_get_float_dcba(const uint16_t *src)
{
float f;
uint32_t i;
i = ntohl(bswap_32((((uint32_t)src[0]) << 16) + src[1]));
memcpy(&f, &i, sizeof(float));
return f;
}
/* Get a float from 4 bytes (Modbus) with swapped bytes (BADC) */
float modbus_get_float_badc(const uint16_t *src)
{
float f;
uint32_t i;
i = ntohl((uint32_t)(bswap_16(src[0]) << 16) + bswap_16(src[1]));
memcpy(&f, &i, sizeof(float));
return f;
}
/* Get a float from 4 bytes (Modbus) with swapped words (CDAB) */
float modbus_get_float_cdab(const uint16_t *src)
{
float f;
uint32_t i;
i = ntohl((((uint32_t)src[1]) << 16) + src[0]);
memcpy(&f, &i, sizeof(float));
return f;
}
/* DEPRECATED - Get a float from 4 bytes in sort of Modbus format */
float modbus_get_float(const uint16_t *src)
{
float f;
uint32_t i;
i = (((uint32_t)src[1]) << 16) + src[0];
memcpy(&f, &i, sizeof(float));
return f;
}
/* Set a float to 4 bytes for Modbus w/o any conversion (ABCD) */
void modbus_set_float_abcd(float f, uint16_t *dest)
{
uint32_t i;
memcpy(&i, &f, sizeof(uint32_t));
i = htonl(i);
dest[0] = (uint16_t)(i >> 16);
dest[1] = (uint16_t)i;
}
/* Set a float to 4 bytes for Modbus with byte and word swap conversion (DCBA) */
void modbus_set_float_dcba(float f, uint16_t *dest)
{
uint32_t i;
memcpy(&i, &f, sizeof(uint32_t));
i = bswap_32(htonl(i));
dest[0] = (uint16_t)(i >> 16);
dest[1] = (uint16_t)i;
}
/* Set a float to 4 bytes for Modbus with byte swap conversion (BADC) */
void modbus_set_float_badc(float f, uint16_t *dest)
{
uint32_t i;
memcpy(&i, &f, sizeof(uint32_t));
i = htonl(i);
dest[0] = (uint16_t)bswap_16(i >> 16);
dest[1] = (uint16_t)bswap_16(i & 0xFFFF);
}
/* Set a float to 4 bytes for Modbus with word swap conversion (CDAB) */
void modbus_set_float_cdab(float f, uint16_t *dest)
{
uint32_t i;
memcpy(&i, &f, sizeof(uint32_t));
i = htonl(i);
dest[0] = (uint16_t)i;
dest[1] = (uint16_t)(i >> 16);
}
/* DEPRECATED - Set a float to 4 bytes in a sort of Modbus format! */
void modbus_set_float(float f, uint16_t *dest)
{
uint32_t i;
memcpy(&i, &f, sizeof(uint32_t));
dest[0] = (uint16_t)i;
dest[1] = (uint16_t)(i >> 16);
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright © 2010-2012 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_PRIVATE_H
#define MODBUS_PRIVATE_H
#ifndef _MSC_VER
# include <stdint.h>
# include <sys/time.h>
#else
# include "stdint.h"
# include <time.h>
typedef int ssize_t;
#endif
#include <sys/types.h>
#include <config.h>
#include "modbus.h"
MODBUS_BEGIN_DECLS
/* It's not really the minimal length (the real one is report slave ID
* in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP
* communications to read many values or write a single one.
* Maximum between :
* - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
* - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
*/
#define _MIN_REQ_LENGTH 12
#define _REPORT_SLAVE_ID 180
#define _MODBUS_EXCEPTION_RSP_LENGTH 5
/* Timeouts in microsecond (0.5 s) */
#define _RESPONSE_TIMEOUT 500000
#define _BYTE_TIMEOUT 500000
typedef enum {
_MODBUS_BACKEND_TYPE_RTU=0,
_MODBUS_BACKEND_TYPE_TCP
} modbus_backend_type_t;
/*
* ---------- Request Indication ----------
* | Client | ---------------------->| Server |
* ---------- Confirmation Response ----------
*/
typedef enum {
/* Request message on the server side */
MSG_INDICATION,
/* Request message on the client side */
MSG_CONFIRMATION
} msg_type_t;
/* This structure reduces the number of params in functions and so
* optimizes the speed of execution (~ 37%). */
typedef struct _sft {
int slave;
int function;
int t_id;
} sft_t;
typedef struct _modbus_backend {
unsigned int backend_type;
unsigned int header_length;
unsigned int checksum_length;
unsigned int max_adu_length;
int (*set_slave) (modbus_t *ctx, int slave);
int (*build_request_basis) (modbus_t *ctx, int function, int addr,
int nb, uint8_t *req);
int (*build_response_basis) (sft_t *sft, uint8_t *rsp);
int (*prepare_response_tid) (const uint8_t *req, int *req_length);
int (*send_msg_pre) (uint8_t *req, int req_length);
ssize_t (*send) (modbus_t *ctx, const uint8_t *req, int req_length);
int (*receive) (modbus_t *ctx, uint8_t *req);
ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length);
int (*check_integrity) (modbus_t *ctx, uint8_t *msg,
const int msg_length);
int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req,
const uint8_t *rsp, int rsp_length);
int (*connect) (modbus_t *ctx);
void (*close) (modbus_t *ctx);
int (*flush) (modbus_t *ctx);
int (*select) (modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length);
void (*free) (modbus_t *ctx);
} modbus_backend_t;
struct _modbus {
/* Slave address */
int slave;
/* Socket or file descriptor */
int s;
int debug;
int error_recovery;
struct timeval response_timeout;
struct timeval byte_timeout;
struct timeval indication_timeout;
const modbus_backend_t *backend;
void *backend_data;
};
void _modbus_init_common(modbus_t *ctx);
void _error_print(modbus_t *ctx, const char *context);
int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type);
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dest, const char *src, size_t dest_size);
#endif
MODBUS_END_DECLS
#endif /* MODBUS_PRIVATE_H */

View File

@@ -0,0 +1,76 @@
/*
* Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_RTU_PRIVATE_H
#define MODBUS_RTU_PRIVATE_H
#ifndef _MSC_VER
#include <stdint.h>
#else
#include "stdint.h"
#endif
#if defined(_WIN32)
#include <windows.h>
#else
#include <termios.h>
#endif
#define _MODBUS_RTU_HEADER_LENGTH 1
#define _MODBUS_RTU_PRESET_REQ_LENGTH 6
#define _MODBUS_RTU_PRESET_RSP_LENGTH 2
#define _MODBUS_RTU_CHECKSUM_LENGTH 2
#if defined(_WIN32)
#if !defined(ENOTSUP)
#define ENOTSUP WSAEOPNOTSUPP
#endif
/* WIN32: struct containing serial handle and a receive buffer */
#define PY_BUF_SIZE 512
struct win32_ser {
/* File handle */
HANDLE fd;
/* Receive buffer */
uint8_t buf[PY_BUF_SIZE];
/* Received chars */
DWORD n_bytes;
};
#endif /* _WIN32 */
typedef struct _modbus_rtu {
/* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X. */
char *device;
/* Bauds: 9600, 19200, 57600, 115200, etc */
int baud;
/* Data bit */
uint8_t data_bit;
/* Stop bit */
uint8_t stop_bit;
/* Parity: 'N', 'O', 'E' */
char parity;
#if defined(_WIN32)
struct win32_ser w_ser;
DCB old_dcb;
#else
/* Save old termios settings */
struct termios old_tios;
#endif
#if HAVE_DECL_TIOCSRS485
int serial_mode;
#endif
#if HAVE_DECL_TIOCM_RTS
int rts;
int rts_delay;
int onebyte_time;
void (*set_rts) (modbus_t *ctx, int on);
#endif
/* To handle many slaves on the same link */
int confirmation_to_ignore;
} modbus_rtu_t;
#endif /* MODBUS_RTU_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/*
* Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_RTU_H
#define MODBUS_RTU_H
#include "modbus.h"
MODBUS_BEGIN_DECLS
/* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5
* RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes
*/
#define MODBUS_RTU_MAX_ADU_LENGTH 256
MODBUS_API modbus_t* modbus_new_rtu(const char *device, int baud, char parity,
int data_bit, int stop_bit);
#define MODBUS_RTU_RS232 0
#define MODBUS_RTU_RS485 1
MODBUS_API int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);
MODBUS_API int modbus_rtu_get_serial_mode(modbus_t *ctx);
#define MODBUS_RTU_RTS_NONE 0
#define MODBUS_RTU_RTS_UP 1
#define MODBUS_RTU_RTS_DOWN 2
MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode);
MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx);
MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on));
MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);
MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx);
MODBUS_END_DECLS
#endif /* MODBUS_RTU_H */

View File

@@ -0,0 +1,44 @@
/*
* Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_TCP_PRIVATE_H
#define MODBUS_TCP_PRIVATE_H
#define _MODBUS_TCP_HEADER_LENGTH 7
#define _MODBUS_TCP_PRESET_REQ_LENGTH 12
#define _MODBUS_TCP_PRESET_RSP_LENGTH 8
#define _MODBUS_TCP_CHECKSUM_LENGTH 0
/* In both structures, the transaction ID must be placed on first position
to have a quick access not dependant of the TCP backend */
typedef struct _modbus_tcp {
/* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b
(page 23/46):
The transaction identifier is used to associate the future response
with the request. This identifier is unique on each TCP connection. */
uint16_t t_id;
/* TCP port */
int port;
/* IP address */
char ip[16];
} modbus_tcp_t;
#define _MODBUS_TCP_PI_NODE_LENGTH 1025
#define _MODBUS_TCP_PI_SERVICE_LENGTH 32
typedef struct _modbus_tcp_pi {
/* Transaction ID */
uint16_t t_id;
/* TCP port */
int port;
/* Node */
char node[_MODBUS_TCP_PI_NODE_LENGTH];
/* Service */
char service[_MODBUS_TCP_PI_SERVICE_LENGTH];
} modbus_tcp_pi_t;
#endif /* MODBUS_TCP_PRIVATE_H */

View File

@@ -0,0 +1,929 @@
/*
* Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#if defined(_WIN32)
# define OS_WIN32
/* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later.
* minwg32 headers check WINVER before allowing the use of these */
# ifndef WINVER
# define WINVER 0x0501
# endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <signal.h>
#include <sys/types.h>
#if defined(_WIN32)
/* Already set in modbus-tcp.h but it seems order matters in VS2005 */
# include <winsock2.h>
# include <ws2tcpip.h>
# define SHUT_RDWR 2
# define close closesocket
#else
# include <sys/socket.h>
# include <sys/ioctl.h>
#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ < 5)
# define OS_BSD
# include <netinet/in_systm.h>
#endif
# include <netinet/in.h>
# include <netinet/ip.h>
# include <netinet/tcp.h>
# include <arpa/inet.h>
# include <netdb.h>
#endif
#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
#if defined(_AIX) && !defined(MSG_DONTWAIT)
#define MSG_DONTWAIT MSG_NONBLOCK
#endif
#include "modbus-private.h"
#include "modbus-tcp.h"
#include "modbus-tcp-private.h"
#ifdef OS_WIN32
static int _modbus_tcp_init_win32(void)
{
/* Initialise Windows Socket API */
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup() returned error code %d\n",
(unsigned int)GetLastError());
errno = EIO;
return -1;
}
return 0;
}
#endif
static int _modbus_set_slave(modbus_t *ctx, int slave)
{
/* Broadcast address is 0 (MODBUS_BROADCAST_ADDRESS) */
if (slave >= 0 && slave <= 247) {
ctx->slave = slave;
} else if (slave == MODBUS_TCP_SLAVE) {
/* The special value MODBUS_TCP_SLAVE (0xFF) can be used in TCP mode to
* restore the default value. */
ctx->slave = slave;
} else {
errno = EINVAL;
return -1;
}
return 0;
}
/* Builds a TCP request header */
static int _modbus_tcp_build_request_basis(modbus_t *ctx, int function,
int addr, int nb,
uint8_t *req)
{
modbus_tcp_t *ctx_tcp = ctx->backend_data;
/* Increase transaction ID */
if (ctx_tcp->t_id < UINT16_MAX)
ctx_tcp->t_id++;
else
ctx_tcp->t_id = 0;
req[0] = ctx_tcp->t_id >> 8;
req[1] = ctx_tcp->t_id & 0x00ff;
/* Protocol Modbus */
req[2] = 0;
req[3] = 0;
/* Length will be defined later by set_req_length_tcp at offsets 4
and 5 */
req[6] = ctx->slave;
req[7] = function;
req[8] = addr >> 8;
req[9] = addr & 0x00ff;
req[10] = nb >> 8;
req[11] = nb & 0x00ff;
return _MODBUS_TCP_PRESET_REQ_LENGTH;
}
/* Builds a TCP response header */
static int _modbus_tcp_build_response_basis(sft_t *sft, uint8_t *rsp)
{
/* Extract from MODBUS Messaging on TCP/IP Implementation
Guide V1.0b (page 23/46):
The transaction identifier is used to associate the future
response with the request. */
rsp[0] = sft->t_id >> 8;
rsp[1] = sft->t_id & 0x00ff;
/* Protocol Modbus */
rsp[2] = 0;
rsp[3] = 0;
/* Length will be set later by send_msg (4 and 5) */
/* The slave ID is copied from the indication */
rsp[6] = sft->slave;
rsp[7] = sft->function;
return _MODBUS_TCP_PRESET_RSP_LENGTH;
}
static int _modbus_tcp_prepare_response_tid(const uint8_t *req, int *req_length)
{
return (req[0] << 8) + req[1];
}
static int _modbus_tcp_send_msg_pre(uint8_t *req, int req_length)
{
/* Substract the header length to the message length */
int mbap_length = req_length - 6;
req[4] = mbap_length >> 8;
req[5] = mbap_length & 0x00FF;
return req_length;
}
static ssize_t _modbus_tcp_send(modbus_t *ctx, const uint8_t *req, int req_length)
{
/* MSG_NOSIGNAL
Requests not to send SIGPIPE on errors on stream oriented
sockets when the other end breaks the connection. The EPIPE
error is still returned. */
return send(ctx->s, (const char *)req, req_length, MSG_NOSIGNAL);
}
static int _modbus_tcp_receive(modbus_t *ctx, uint8_t *req) {
return _modbus_receive_msg(ctx, req, MSG_INDICATION);
}
static ssize_t _modbus_tcp_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length) {
return recv(ctx->s, (char *)rsp, rsp_length, 0);
}
static int _modbus_tcp_check_integrity(modbus_t *ctx, uint8_t *msg, const int msg_length)
{
return msg_length;
}
static int _modbus_tcp_pre_check_confirmation(modbus_t *ctx, const uint8_t *req,
const uint8_t *rsp, int rsp_length)
{
/* Check transaction ID */
if (req[0] != rsp[0] || req[1] != rsp[1]) {
if (ctx->debug) {
fprintf(stderr, "Invalid transaction ID received 0x%X (not 0x%X)\n",
(rsp[0] << 8) + rsp[1], (req[0] << 8) + req[1]);
}
errno = EMBBADDATA;
return -1;
}
/* Check protocol ID */
if (rsp[2] != 0x0 && rsp[3] != 0x0) {
if (ctx->debug) {
fprintf(stderr, "Invalid protocol ID received 0x%X (not 0x0)\n",
(rsp[2] << 8) + rsp[3]);
}
errno = EMBBADDATA;
return -1;
}
return 0;
}
static int _modbus_tcp_set_ipv4_options(int s)
{
int rc;
int option;
/* Set the TCP no delay flag */
/* SOL_TCP = IPPROTO_TCP */
option = 1;
rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
(const void *)&option, sizeof(int));
if (rc == -1) {
return -1;
}
/* If the OS does not offer SOCK_NONBLOCK, fall back to setting FIONBIO to
* make sockets non-blocking */
/* Do not care about the return value, this is optional */
#if !defined(SOCK_NONBLOCK) && defined(FIONBIO)
#ifdef OS_WIN32
{
/* Setting FIONBIO expects an unsigned long according to MSDN */
u_long loption = 1;
ioctlsocket(s, FIONBIO, &loption);
}
#else
option = 1;
ioctl(s, FIONBIO, &option);
#endif
#endif
#ifndef OS_WIN32
/**
* Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
* necessary to workaround that problem.
**/
/* Set the IP low delay option */
option = IPTOS_LOWDELAY;
rc = setsockopt(s, IPPROTO_IP, IP_TOS,
(const void *)&option, sizeof(int));
if (rc == -1) {
return -1;
}
#endif
return 0;
}
static int _connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen,
const struct timeval *ro_tv)
{
int rc = connect(sockfd, addr, addrlen);
#ifdef OS_WIN32
int wsaError = 0;
if (rc == -1) {
wsaError = WSAGetLastError();
}
if (wsaError == WSAEWOULDBLOCK || wsaError == WSAEINPROGRESS) {
#else
if (rc == -1 && errno == EINPROGRESS) {
#endif
fd_set wset;
int optval;
socklen_t optlen = sizeof(optval);
struct timeval tv = *ro_tv;
/* Wait to be available in writing */
FD_ZERO(&wset);
FD_SET(sockfd, &wset);
rc = select(sockfd + 1, NULL, &wset, NULL, &tv);
if (rc <= 0) {
/* Timeout or fail */
return -1;
}
/* The connection is established if SO_ERROR and optval are set to 0 */
rc = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen);
if (rc == 0 && optval == 0) {
return 0;
} else {
errno = ECONNREFUSED;
return -1;
}
}
return rc;
}
/* Establishes a modbus TCP connection with a Modbus server. */
static int _modbus_tcp_connect(modbus_t *ctx)
{
int rc;
/* Specialized version of sockaddr for Internet socket address (same size) */
struct sockaddr_in addr;
modbus_tcp_t *ctx_tcp = ctx->backend_data;
int flags = SOCK_STREAM;
#ifdef OS_WIN32
if (_modbus_tcp_init_win32() == -1) {
return -1;
}
#endif
#ifdef SOCK_CLOEXEC
flags |= SOCK_CLOEXEC;
#endif
#ifdef SOCK_NONBLOCK
flags |= SOCK_NONBLOCK;
#endif
ctx->s = socket(PF_INET, flags, 0);
if (ctx->s == -1) {
return -1;
}
rc = _modbus_tcp_set_ipv4_options(ctx->s);
if (rc == -1) {
close(ctx->s);
ctx->s = -1;
return -1;
}
if (ctx->debug) {
printf("Connecting to %s:%d\n", ctx_tcp->ip, ctx_tcp->port);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(ctx_tcp->port);
addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);
rc = _connect(ctx->s, (struct sockaddr *)&addr, sizeof(addr), &ctx->response_timeout);
if (rc == -1) {
close(ctx->s);
ctx->s = -1;
return -1;
}
return 0;
}
/* Establishes a modbus TCP PI connection with a Modbus server. */
static int _modbus_tcp_pi_connect(modbus_t *ctx)
{
int rc;
struct addrinfo *ai_list;
struct addrinfo *ai_ptr;
struct addrinfo ai_hints;
modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data;
#ifdef OS_WIN32
if (_modbus_tcp_init_win32() == -1) {
return -1;
}
#endif
memset(&ai_hints, 0, sizeof(ai_hints));
#ifdef AI_ADDRCONFIG
ai_hints.ai_flags |= AI_ADDRCONFIG;
#endif
ai_hints.ai_family = AF_UNSPEC;
ai_hints.ai_socktype = SOCK_STREAM;
ai_hints.ai_addr = NULL;
ai_hints.ai_canonname = NULL;
ai_hints.ai_next = NULL;
ai_list = NULL;
rc = getaddrinfo(ctx_tcp_pi->node, ctx_tcp_pi->service,
&ai_hints, &ai_list);
if (rc != 0) {
if (ctx->debug) {
fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc));
}
errno = ECONNREFUSED;
return -1;
}
for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
int flags = ai_ptr->ai_socktype;
int s;
#ifdef SOCK_CLOEXEC
flags |= SOCK_CLOEXEC;
#endif
#ifdef SOCK_NONBLOCK
flags |= SOCK_NONBLOCK;
#endif
s = socket(ai_ptr->ai_family, flags, ai_ptr->ai_protocol);
if (s < 0)
continue;
if (ai_ptr->ai_family == AF_INET)
_modbus_tcp_set_ipv4_options(s);
if (ctx->debug) {
printf("Connecting to [%s]:%s\n", ctx_tcp_pi->node, ctx_tcp_pi->service);
}
rc = _connect(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen, &ctx->response_timeout);
if (rc == -1) {
close(s);
continue;
}
ctx->s = s;
break;
}
freeaddrinfo(ai_list);
if (ctx->s < 0) {
return -1;
}
return 0;
}
/* Closes the network connection and socket in TCP mode */
static void _modbus_tcp_close(modbus_t *ctx)
{
if (ctx->s != -1) {
shutdown(ctx->s, SHUT_RDWR);
close(ctx->s);
ctx->s = -1;
}
}
static int _modbus_tcp_flush(modbus_t *ctx)
{
int rc;
int rc_sum = 0;
do {
/* Extract the garbage from the socket */
char devnull[MODBUS_TCP_MAX_ADU_LENGTH];
#ifndef OS_WIN32
rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT);
#else
/* On Win32, it's a bit more complicated to not wait */
fd_set rset;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rset);
FD_SET(ctx->s, &rset);
rc = select(ctx->s+1, &rset, NULL, NULL, &tv);
if (rc == -1) {
return -1;
}
if (rc == 1) {
/* There is data to flush */
rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, 0);
}
#endif
if (rc > 0) {
rc_sum += rc;
}
} while (rc == MODBUS_TCP_MAX_ADU_LENGTH);
return rc_sum;
}
/* Listens for any request from one or many modbus masters in TCP */
int modbus_tcp_listen(modbus_t *ctx, int nb_connection)
{
int new_s;
int enable;
int flags;
struct sockaddr_in addr;
modbus_tcp_t *ctx_tcp;
if (ctx == NULL) {
errno = EINVAL;
return -1;
}
ctx_tcp = ctx->backend_data;
#ifdef OS_WIN32
if (_modbus_tcp_init_win32() == -1) {
return -1;
}
#endif
flags = SOCK_STREAM;
#ifdef SOCK_CLOEXEC
flags |= SOCK_CLOEXEC;
#endif
new_s = socket(PF_INET, flags, IPPROTO_TCP);
if (new_s == -1) {
return -1;
}
enable = 1;
if (setsockopt(new_s, SOL_SOCKET, SO_REUSEADDR,
(char *)&enable, sizeof(enable)) == -1) {
close(new_s);
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
/* If the modbus port is < to 1024, we need the setuid root. */
addr.sin_port = htons(ctx_tcp->port);
if (ctx_tcp->ip[0] == '0') {
/* Listen any addresses */
addr.sin_addr.s_addr = htonl(INADDR_ANY);
} else {
/* Listen only specified IP address */
addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip);
}
if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
close(new_s);
return -1;
}
if (listen(new_s, nb_connection) == -1) {
close(new_s);
return -1;
}
return new_s;
}
int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection)
{
int rc;
struct addrinfo *ai_list;
struct addrinfo *ai_ptr;
struct addrinfo ai_hints;
const char *node;
const char *service;
int new_s;
modbus_tcp_pi_t *ctx_tcp_pi;
if (ctx == NULL) {
errno = EINVAL;
return -1;
}
ctx_tcp_pi = ctx->backend_data;
#ifdef OS_WIN32
if (_modbus_tcp_init_win32() == -1) {
return -1;
}
#endif
if (ctx_tcp_pi->node[0] == 0) {
node = NULL; /* == any */
} else {
node = ctx_tcp_pi->node;
}
if (ctx_tcp_pi->service[0] == 0) {
service = "502";
} else {
service = ctx_tcp_pi->service;
}
memset(&ai_hints, 0, sizeof (ai_hints));
/* If node is not NULL, than the AI_PASSIVE flag is ignored. */
ai_hints.ai_flags |= AI_PASSIVE;
#ifdef AI_ADDRCONFIG
ai_hints.ai_flags |= AI_ADDRCONFIG;
#endif
ai_hints.ai_family = AF_UNSPEC;
ai_hints.ai_socktype = SOCK_STREAM;
ai_hints.ai_addr = NULL;
ai_hints.ai_canonname = NULL;
ai_hints.ai_next = NULL;
ai_list = NULL;
rc = getaddrinfo(node, service, &ai_hints, &ai_list);
if (rc != 0) {
if (ctx->debug) {
fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc));
}
errno = ECONNREFUSED;
return -1;
}
new_s = -1;
for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
int flags = ai_ptr->ai_socktype;
int s;
#ifdef SOCK_CLOEXEC
flags |= SOCK_CLOEXEC;
#endif
s = socket(ai_ptr->ai_family, flags, ai_ptr->ai_protocol);
if (s < 0) {
if (ctx->debug) {
perror("socket");
}
continue;
} else {
int enable = 1;
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(void *)&enable, sizeof (enable));
if (rc != 0) {
close(s);
if (ctx->debug) {
perror("setsockopt");
}
continue;
}
}
rc = bind(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
if (rc != 0) {
close(s);
if (ctx->debug) {
perror("bind");
}
continue;
}
rc = listen(s, nb_connection);
if (rc != 0) {
close(s);
if (ctx->debug) {
perror("listen");
}
continue;
}
new_s = s;
break;
}
freeaddrinfo(ai_list);
if (new_s < 0) {
return -1;
}
return new_s;
}
int modbus_tcp_accept(modbus_t *ctx, int *s)
{
struct sockaddr_in addr;
socklen_t addrlen;
if (ctx == NULL) {
errno = EINVAL;
return -1;
}
addrlen = sizeof(addr);
#ifdef HAVE_ACCEPT4
/* Inherit socket flags and use accept4 call */
ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
#else
ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen);
#endif
if (ctx->s == -1) {
return -1;
}
if (ctx->debug) {
printf("The client connection from %s is accepted\n",
inet_ntoa(addr.sin_addr));
}
return ctx->s;
}
int modbus_tcp_pi_accept(modbus_t *ctx, int *s)
{
struct sockaddr_storage addr;
socklen_t addrlen;
if (ctx == NULL) {
errno = EINVAL;
return -1;
}
addrlen = sizeof(addr);
#ifdef HAVE_ACCEPT4
/* Inherit socket flags and use accept4 call */
ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
#else
ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen);
#endif
if (ctx->s == -1) {
return -1;
}
if (ctx->debug) {
printf("The client connection is accepted.\n");
}
return ctx->s;
}
static int _modbus_tcp_select(modbus_t *ctx, fd_set *rset, struct timeval *tv, int length_to_read)
{
int s_rc;
while ((s_rc = select(ctx->s+1, rset, NULL, NULL, tv)) == -1) {
if (errno == EINTR) {
if (ctx->debug) {
fprintf(stderr, "A non blocked signal was caught\n");
}
/* Necessary after an error */
FD_ZERO(rset);
FD_SET(ctx->s, rset);
} else {
return -1;
}
}
if (s_rc == 0) {
errno = ETIMEDOUT;
return -1;
}
return s_rc;
}
static void _modbus_tcp_free(modbus_t *ctx) {
free(ctx->backend_data);
free(ctx);
}
const modbus_backend_t _modbus_tcp_backend = {
_MODBUS_BACKEND_TYPE_TCP,
_MODBUS_TCP_HEADER_LENGTH,
_MODBUS_TCP_CHECKSUM_LENGTH,
MODBUS_TCP_MAX_ADU_LENGTH,
_modbus_set_slave,
_modbus_tcp_build_request_basis,
_modbus_tcp_build_response_basis,
_modbus_tcp_prepare_response_tid,
_modbus_tcp_send_msg_pre,
_modbus_tcp_send,
_modbus_tcp_receive,
_modbus_tcp_recv,
_modbus_tcp_check_integrity,
_modbus_tcp_pre_check_confirmation,
_modbus_tcp_connect,
_modbus_tcp_close,
_modbus_tcp_flush,
_modbus_tcp_select,
_modbus_tcp_free
};
const modbus_backend_t _modbus_tcp_pi_backend = {
_MODBUS_BACKEND_TYPE_TCP,
_MODBUS_TCP_HEADER_LENGTH,
_MODBUS_TCP_CHECKSUM_LENGTH,
MODBUS_TCP_MAX_ADU_LENGTH,
_modbus_set_slave,
_modbus_tcp_build_request_basis,
_modbus_tcp_build_response_basis,
_modbus_tcp_prepare_response_tid,
_modbus_tcp_send_msg_pre,
_modbus_tcp_send,
_modbus_tcp_receive,
_modbus_tcp_recv,
_modbus_tcp_check_integrity,
_modbus_tcp_pre_check_confirmation,
_modbus_tcp_pi_connect,
_modbus_tcp_close,
_modbus_tcp_flush,
_modbus_tcp_select,
_modbus_tcp_free
};
modbus_t* modbus_new_tcp(const char *ip, int port)
{
modbus_t *ctx;
modbus_tcp_t *ctx_tcp;
size_t dest_size;
size_t ret_size;
#if defined(OS_BSD)
/* MSG_NOSIGNAL is unsupported on *BSD so we install an ignore
handler for SIGPIPE. */
struct sigaction sa;
sa.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &sa, NULL) < 0) {
/* The debug flag can't be set here... */
fprintf(stderr, "Could not install SIGPIPE handler.\n");
return NULL;
}
#endif
ctx = (modbus_t *)malloc(sizeof(modbus_t));
if (ctx == NULL) {
return NULL;
}
_modbus_init_common(ctx);
/* Could be changed after to reach a remote serial Modbus device */
ctx->slave = MODBUS_TCP_SLAVE;
ctx->backend = &_modbus_tcp_backend;
ctx->backend_data = (modbus_tcp_t *)malloc(sizeof(modbus_tcp_t));
if (ctx->backend_data == NULL) {
modbus_free(ctx);
errno = ENOMEM;
return NULL;
}
ctx_tcp = (modbus_tcp_t *)ctx->backend_data;
if (ip != NULL) {
dest_size = sizeof(char) * 16;
ret_size = strlcpy(ctx_tcp->ip, ip, dest_size);
if (ret_size == 0) {
fprintf(stderr, "The IP string is empty\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
if (ret_size >= dest_size) {
fprintf(stderr, "The IP string has been truncated\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
} else {
ctx_tcp->ip[0] = '0';
}
ctx_tcp->port = port;
ctx_tcp->t_id = 0;
return ctx;
}
modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
{
modbus_t *ctx;
modbus_tcp_pi_t *ctx_tcp_pi;
size_t dest_size;
size_t ret_size;
ctx = (modbus_t *)malloc(sizeof(modbus_t));
if (ctx == NULL) {
return NULL;
}
_modbus_init_common(ctx);
/* Could be changed after to reach a remote serial Modbus device */
ctx->slave = MODBUS_TCP_SLAVE;
ctx->backend = &_modbus_tcp_pi_backend;
ctx->backend_data = (modbus_tcp_pi_t *)malloc(sizeof(modbus_tcp_pi_t));
if (ctx->backend_data == NULL) {
modbus_free(ctx);
errno = ENOMEM;
return NULL;
}
ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data;
if (node == NULL) {
/* The node argument can be empty to indicate any hosts */
ctx_tcp_pi->node[0] = 0;
} else {
dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH;
ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size);
if (ret_size == 0) {
fprintf(stderr, "The node string is empty\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
if (ret_size >= dest_size) {
fprintf(stderr, "The node string has been truncated\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
}
if (service != NULL) {
dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH;
ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size);
} else {
/* Empty service is not allowed, error catched below. */
ret_size = 0;
}
if (ret_size == 0) {
fprintf(stderr, "The service string is empty\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
if (ret_size >= dest_size) {
fprintf(stderr, "The service string has been truncated\n");
modbus_free(ctx);
errno = EINVAL;
return NULL;
}
ctx_tcp_pi->t_id = 0;
return ctx;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright © 2001-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_TCP_H
#define MODBUS_TCP_H
#include "modbus.h"
MODBUS_BEGIN_DECLS
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Win32 with MinGW, supplement to <errno.h> */
#include <winsock2.h>
#if !defined(ECONNRESET)
#define ECONNRESET WSAECONNRESET
#endif
#if !defined(ECONNREFUSED)
#define ECONNREFUSED WSAECONNREFUSED
#endif
#if !defined(ETIMEDOUT)
#define ETIMEDOUT WSAETIMEDOUT
#endif
#if !defined(ENOPROTOOPT)
#define ENOPROTOOPT WSAENOPROTOOPT
#endif
#if !defined(EINPROGRESS)
#define EINPROGRESS WSAEINPROGRESS
#endif
#endif
#define MODBUS_TCP_DEFAULT_PORT 502
#define MODBUS_TCP_SLAVE 0xFF
/* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5
* TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes
*/
#define MODBUS_TCP_MAX_ADU_LENGTH 260
MODBUS_API modbus_t* modbus_new_tcp(const char *ip_address, int port);
MODBUS_API int modbus_tcp_listen(modbus_t *ctx, int nb_connection);
MODBUS_API int modbus_tcp_accept(modbus_t *ctx, int *s);
MODBUS_API modbus_t* modbus_new_tcp_pi(const char *node, const char *service);
MODBUS_API int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection);
MODBUS_API int modbus_tcp_pi_accept(modbus_t *ctx, int *s);
MODBUS_END_DECLS
#endif /* MODBUS_TCP_H */

View File

@@ -0,0 +1,53 @@
/*
* Copyright © 2010-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MODBUS_VERSION_H
#define MODBUS_VERSION_H
/* The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MAJOR (@LIBMODBUS_VERSION_MAJOR@)
/* The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MINOR (@LIBMODBUS_VERSION_MINOR@)
/* The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MICRO (@LIBMODBUS_VERSION_MICRO@)
/* The full version, like 1.2.3 */
#define LIBMODBUS_VERSION @LIBMODBUS_VERSION@
/* The full version, in string form (suited for string concatenation)
*/
#define LIBMODBUS_VERSION_STRING "@LIBMODBUS_VERSION@"
/* Numerically encoded version, eg. v1.2.3 is 0x010203 */
#define LIBMODBUS_VERSION_HEX ((LIBMODBUS_VERSION_MAJOR << 16) | \
(LIBMODBUS_VERSION_MINOR << 8) | \
(LIBMODBUS_VERSION_MICRO << 0))
/* Evaluates to True if the version is greater than @major, @minor and @micro
*/
#define LIBMODBUS_VERSION_CHECK(major,minor,micro) \
(LIBMODBUS_VERSION_MAJOR > (major) || \
(LIBMODBUS_VERSION_MAJOR == (major) && \
LIBMODBUS_VERSION_MINOR > (minor)) || \
(LIBMODBUS_VERSION_MAJOR == (major) && \
LIBMODBUS_VERSION_MINOR == (minor) && \
LIBMODBUS_VERSION_MICRO >= (micro)))
#endif /* MODBUS_VERSION_H */

1909
libmodbus-master/modbus.c Normal file

File diff suppressed because it is too large Load Diff

293
libmodbus-master/modbus.h Normal file
View File

@@ -0,0 +1,293 @@
/*
* Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef MODBUS_H
#define MODBUS_H
/* Add this for macros that defined unix flavor */
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
#ifndef _MSC_VER
#include <stdint.h>
#else
#include "stdint.h"
#endif
#include "modbus-version.h"
#if defined(_MSC_VER)
# if defined(DLLBUILD)
/* define DLLBUILD when building the DLL */
# define MODBUS_API __declspec(dllexport)
# else
# define MODBUS_API __declspec(dllimport)
# endif
#else
# define MODBUS_API
#endif
#ifdef __cplusplus
# define MODBUS_BEGIN_DECLS extern "C" {
# define MODBUS_END_DECLS }
#else
# define MODBUS_BEGIN_DECLS
# define MODBUS_END_DECLS
#endif
MODBUS_BEGIN_DECLS
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef OFF
#define OFF 0
#endif
#ifndef ON
#define ON 1
#endif
/* Modbus function codes */
#define MODBUS_FC_READ_COILS 0x01
#define MODBUS_FC_READ_DISCRETE_INPUTS 0x02
#define MODBUS_FC_READ_HOLDING_REGISTERS 0x03
#define MODBUS_FC_READ_INPUT_REGISTERS 0x04
#define MODBUS_FC_WRITE_SINGLE_COIL 0x05
#define MODBUS_FC_WRITE_SINGLE_REGISTER 0x06
#define MODBUS_FC_READ_EXCEPTION_STATUS 0x07
#define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F
#define MODBUS_FC_WRITE_MULTIPLE_REGISTERS 0x10
#define MODBUS_FC_REPORT_SLAVE_ID 0x11
#define MODBUS_FC_MASK_WRITE_REGISTER 0x16
#define MODBUS_FC_WRITE_AND_READ_REGISTERS 0x17
#define MODBUS_BROADCAST_ADDRESS 0
/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
* Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0)
* (chapter 6 section 11 page 29)
* Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
*/
#define MODBUS_MAX_READ_BITS 2000
#define MODBUS_MAX_WRITE_BITS 1968
/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15)
* Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
* (chapter 6 section 12 page 31)
* Quantity of Registers to write (2 bytes) 1 to 123 (0x7B)
* (chapter 6 section 17 page 38)
* Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
*/
#define MODBUS_MAX_READ_REGISTERS 125
#define MODBUS_MAX_WRITE_REGISTERS 123
#define MODBUS_MAX_WR_WRITE_REGISTERS 121
#define MODBUS_MAX_WR_READ_REGISTERS 125
/* The size of the MODBUS PDU is limited by the size constraint inherited from
* the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256
* bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server
* address (1 byte) - CRC (2 bytes) = 253 bytes.
*/
#define MODBUS_MAX_PDU_LENGTH 253
/* Consequently:
* - RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256
* bytes.
* - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.
* so the maximum of both backend in 260 bytes. This size can used to allocate
* an array of bytes to store responses and it will be compatible with the two
* backends.
*/
#define MODBUS_MAX_ADU_LENGTH 260
/* Random number to avoid errno conflicts */
#define MODBUS_ENOBASE 112345678
/* Protocol exceptions */
enum {
MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01,
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE,
MODBUS_EXCEPTION_ACKNOWLEDGE,
MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY,
MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE,
MODBUS_EXCEPTION_MEMORY_PARITY,
MODBUS_EXCEPTION_NOT_DEFINED,
MODBUS_EXCEPTION_GATEWAY_PATH,
MODBUS_EXCEPTION_GATEWAY_TARGET,
MODBUS_EXCEPTION_MAX
};
#define EMBXILFUN (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_FUNCTION)
#define EMBXILADD (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS)
#define EMBXILVAL (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE)
#define EMBXSFAIL (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE)
#define EMBXACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_ACKNOWLEDGE)
#define EMBXSBUSY (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY)
#define EMBXNACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE)
#define EMBXMEMPAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_MEMORY_PARITY)
#define EMBXGPATH (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_PATH)
#define EMBXGTAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_TARGET)
/* Native libmodbus error codes */
#define EMBBADCRC (EMBXGTAR + 1)
#define EMBBADDATA (EMBXGTAR + 2)
#define EMBBADEXC (EMBXGTAR + 3)
#define EMBUNKEXC (EMBXGTAR + 4)
#define EMBMDATA (EMBXGTAR + 5)
#define EMBBADSLAVE (EMBXGTAR + 6)
extern const unsigned int libmodbus_version_major;
extern const unsigned int libmodbus_version_minor;
extern const unsigned int libmodbus_version_micro;
typedef struct _modbus modbus_t;
typedef struct _modbus_mapping_t {
int nb_bits;
int start_bits;
int nb_input_bits;
int start_input_bits;
int nb_input_registers;
int start_input_registers;
int nb_registers;
int start_registers;
uint8_t *tab_bits;
uint8_t *tab_input_bits;
uint16_t *tab_input_registers;
uint16_t *tab_registers;
} modbus_mapping_t;
typedef enum
{
MODBUS_ERROR_RECOVERY_NONE = 0,
MODBUS_ERROR_RECOVERY_LINK = (1<<1),
MODBUS_ERROR_RECOVERY_PROTOCOL = (1<<2)
} modbus_error_recovery_mode;
MODBUS_API int modbus_set_slave(modbus_t* ctx, int slave);
MODBUS_API int modbus_get_slave(modbus_t* ctx);
MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);
MODBUS_API int modbus_set_socket(modbus_t *ctx, int s);
MODBUS_API int modbus_get_socket(modbus_t *ctx);
MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
MODBUS_API int modbus_get_header_length(modbus_t *ctx);
MODBUS_API int modbus_connect(modbus_t *ctx);
MODBUS_API void modbus_close(modbus_t *ctx);
MODBUS_API void modbus_free(modbus_t *ctx);
MODBUS_API int modbus_flush(modbus_t *ctx);
MODBUS_API int modbus_set_debug(modbus_t *ctx, int flag);
MODBUS_API const char *modbus_strerror(int errnum);
MODBUS_API int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
MODBUS_API int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
MODBUS_API int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
MODBUS_API int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status);
MODBUS_API int modbus_write_register(modbus_t *ctx, int reg_addr, int value);
MODBUS_API int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *data);
MODBUS_API int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data);
MODBUS_API int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint16_t or_mask);
MODBUS_API int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb,
const uint16_t *src, int read_addr, int read_nb,
uint16_t *dest);
MODBUS_API int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);
MODBUS_API modbus_mapping_t* modbus_mapping_new_start_address(
unsigned int start_bits, unsigned int nb_bits,
unsigned int start_input_bits, unsigned int nb_input_bits,
unsigned int start_registers, unsigned int nb_registers,
unsigned int start_input_registers, unsigned int nb_input_registers);
MODBUS_API modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
int nb_registers, int nb_input_registers);
MODBUS_API void modbus_mapping_free(modbus_mapping_t *mb_mapping);
MODBUS_API int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length);
MODBUS_API int modbus_receive(modbus_t *ctx, uint8_t *req);
MODBUS_API int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);
MODBUS_API int modbus_reply(modbus_t *ctx, const uint8_t *req,
int req_length, modbus_mapping_t *mb_mapping);
MODBUS_API int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
unsigned int exception_code);
/**
* UTILS FUNCTIONS
**/
#define MODBUS_GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF)
#define MODBUS_GET_LOW_BYTE(data) ((data) & 0xFF)
#define MODBUS_GET_INT64_FROM_INT16(tab_int16, index) \
(((int64_t)tab_int16[(index) ] << 48) + \
((int64_t)tab_int16[(index) + 1] << 32) + \
((int64_t)tab_int16[(index) + 2] << 16) + \
(int64_t)tab_int16[(index) + 3])
#define MODBUS_GET_INT32_FROM_INT16(tab_int16, index) ((tab_int16[(index)] << 16) + tab_int16[(index) + 1])
#define MODBUS_GET_INT16_FROM_INT8(tab_int8, index) ((tab_int8[(index)] << 8) + tab_int8[(index) + 1])
#define MODBUS_SET_INT16_TO_INT8(tab_int8, index, value) \
do { \
tab_int8[(index)] = (value) >> 8; \
tab_int8[(index) + 1] = (value) & 0xFF; \
} while (0)
#define MODBUS_SET_INT32_TO_INT16(tab_int16, index, value) \
do { \
tab_int16[(index) ] = (value) >> 16; \
tab_int16[(index) + 1] = (value); \
} while (0)
#define MODBUS_SET_INT64_TO_INT16(tab_int16, index, value) \
do { \
tab_int16[(index) ] = (value) >> 48; \
tab_int16[(index) + 1] = (value) >> 32; \
tab_int16[(index) + 2] = (value) >> 16; \
tab_int16[(index) + 3] = (value); \
} while (0)
MODBUS_API void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value);
MODBUS_API void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits,
const uint8_t *tab_byte);
MODBUS_API uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx, unsigned int nb_bits);
MODBUS_API float modbus_get_float(const uint16_t *src);
MODBUS_API float modbus_get_float_abcd(const uint16_t *src);
MODBUS_API float modbus_get_float_dcba(const uint16_t *src);
MODBUS_API float modbus_get_float_badc(const uint16_t *src);
MODBUS_API float modbus_get_float_cdab(const uint16_t *src);
MODBUS_API void modbus_set_float(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_abcd(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_dcba(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_badc(float f, uint16_t *dest);
MODBUS_API void modbus_set_float_cdab(float f, uint16_t *dest);
#include "modbus-tcp.h"
#include "modbus-rtu.h"
MODBUS_END_DECLS
#endif /* MODBUS_H */

View File

@@ -0,0 +1,62 @@
# Windows makefile
# --
# use mingw make
# Get make-3.82-5-mingw32-bin.tar.lzma from
# http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/make-3.82-mingw32/
# --
# Set CC=gcc or CC=cl for the pre-defined compilers
# before using this Makefile
# --
# Compile and link the bandwidth and random tests.
# Build modbus.dll and the import library before building the tests
# modbus.lib/libmodbus.a (the import library) should be in this directory
# modbus.dll should be in this directory or in path
INCLUDES:=-I../.. -I.. -I.
ifeq ($(CC),cl)
DEFS+=-D_CRT_SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC_NO_DEPRECATE=1
CFLAGS=-Zi -W3 -MT -ID:/include/msvc_std
LDOPTS=-link -incremental:NO
LDLIBS=-Fe$@ ws2_32.lib modbus.lib $(LDOPTS)
RES:=res
RCOUT=
endif
ifeq ($(CC),gcc)
CFLAGS=-g -Wall -O -static -static-libgcc
LDLIBS=-o$@ -lws2_32 -luser32 -L. -lmodbus
LDOPTS=
RES:=o
RCOUT=-o$@
endif
CFLAGS+=-DHAVE_CONFIG_H $(DEFS) $(INCLUDES)
.SUFFIXES:
.SUFFIXES: .c .rc .$(RES) .$(oo)
# pattern rule for resources
%.$(RES) : %.rc
$(RC) $< $(RCOUT)
vpath %.c ../../tests
vpath %.h ../src
all: random-test-client random-test-server bandwidth-client bandwidth-server-one
random-test-client: random-test-client.c
$(LINK.c) $^ $(LDLIBS)
random-test-server: random-test-server.c
$(LINK.c) $^ $(LDLIBS)
bandwidth-server-one: bandwidth-server-one.c
$(LINK.c) $^ $(LDLIBS)
bandwidth-client: bandwidth-client.c
$(LINK.c) $^ $(LDLIBS)
clean:
-@cmd "/c del /Q /S $(OBJS) *.o *.obj *.exe *.pdb *.ilk *.ncb *.res *.dll *.exp *.lib *.ncb *.a *.map *.asm" > NUL: 2>&1

View File

@@ -0,0 +1,20 @@
Intro
-----
This directory contains the project file for Visual Studio 2008 to build
modbus.dll and the import library modbus.lib.
The project file looks for D:/include/msvc_std to find stdint.h.
See ../../README.md file.
config.h and ../modbus-version.h are generated using configure.js.
Run
cscript configure.js
or
wscript configure.js
or
double click configure.js to generate these files.
To get project file for Visual Studio 2005 open copy of file modbus.vcproj in
editor and change attribute `Version` of `VisualStudioProject` tag to "8,00".

View File

@@ -0,0 +1,167 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */
/* Define to 1 if you have the declaration of `TIOCSRS485', and to 0 if you
don't. */
/* #undef HAVE_DECL_TIOCSRS485 */
/* Define to 1 if you have the declaration of `__CYGWIN__', and to 0 if you
don't. */
/* #undef HAVE_DECL___CYGWIN__ */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the `gettimeofday' function. */
/* #undef HAVE_GETTIMEOFDAY */
/* Define to 1 if you have the `inet_ntoa' function. */
/* #undef HAVE_INET_NTOA */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/serial.h> header file. */
/* #undef HAVE_LINUX_SERIAL_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Define to 1 if you have the <netinet/tcp.h> header file. */
/* #undef HAVE_NETINET_TCP_H */
/* Define to 1 if you have the `select' function. */
/* #undef HAVE_SELECT */
/* Define to 1 if you have the `socket' function. */
/* #undef HAVE_SOCKET */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
/* #undef HAVE_STRLCPY */
/* Define to 1 if you have the <sys/ioctl.h> header file. */
/* #undef HAVE_SYS_IOCTL_H */
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
/* #undef HAVE_SYS_TIME_H */
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <termios.h> header file. */
/* #undef HAVE_TERMIOS_H */
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the `vfork' function. */
/* #undef HAVE_VFORK */
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the <winsock2.h> header file. */
#define HAVE_WINSOCK2_H 1
/* Define to 1 if `fork' works. */
/* #undef HAVE_WORKING_FORK */
/* Define to 1 if `vfork' works. */
/* #undef HAVE_WORKING_VFORK */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* #undef LT_OBJDIR */
/* Name of package */
#define PACKAGE "libmodbus"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://github.com/stephane/libmodbus/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libmodbus"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libmodbus @LIBMODBUS_VERSION@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libmodbus"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "@LIBMODBUS_VERSION@"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
/* #undef TIME_WITH_SYS_TIME */
/* Version number of package */
#define VERSION "@LIBMODBUS_VERSION@"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define as `fork' if `vfork' does not work. */
#define vfork fork

View File

@@ -0,0 +1,163 @@
/* Configure script for modbus.dll, specific for Windows with Scripting Host.
*
* Inspired by configure.js from libxml2
*
* oldfaber < oldfaber _at_ gmail _dot_ com >
*
*/
/* The source directory, relative to the one where this file resides. */
var srcDir = "..";
/* Base name of what we are building. */
var baseName = "modbus";
/* Configure file template and output file */
var configFile = srcDir + "\\..\\configure.ac";
/* Input and output files for the modbus-version.h include */
var newfile;
/* Version strings for the binary distribution. Will be filled later in the code. */
var verMajor;
var verMinor;
var verMicro;
/* modbus features. */
var dryRun = false;
/* Win32 build options. NOT used yet */
var compiler = "msvc";
/* Local stuff */
var error = 0;
/* Filename */
var newFile;
/* Displays the details about how to use this script. */
function usage() {
var txt;
txt = "Usage:\n";
txt += " cscript " + WScript.ScriptName + " <options>\n";
txt += " cscript " + WScript.ScriptName + " help\n\n";
txt += "Options can be specified in the form <option>=<value>, where the value is\n";
txt += "either 'yes' or 'no', if not stated otherwise.\n\n";
txt += "\nModbus library configure options, default value given in parentheses:\n\n";
txt += " dry-run: Run configure without creating files (" + (dryRun ? "yes" : "no") + ")\n";
txt += "\nWin32 build options, default value given in parentheses:\n\n";
txt += " compiler: Compiler to be used [msvc|mingw] (" + compiler + ")\n";
WScript.Echo(txt);
}
/* read the version from the configuration file */
function readVersion() {
var fso, cf, ln, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
cf = fso.OpenTextFile(configFile, 1);
while (cf.AtEndOfStream !== true) {
ln = cf.ReadLine();
s = new String(ln);
if (s.search(/^m4_define\(\[libmodbus_version_major/) != -1) {
verMajor = s.substr(s.indexOf(",") + 3, 1);
} else if (s.search(/^m4_define\(\[libmodbus_version_minor/) != -1) {
verMinor = s.substr(s.indexOf(",") + 3, 1);
} else if (s.search(/^m4_define\(\[libmodbus_version_micro/) != -1) {
verMicro = s.substr(s.indexOf(",") + 3, 1);
}
}
cf.Close();
}
/* create the versioned file */
function createVersionedFile(newfile, unversioned) {
var fso, ofi, of, ln, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
ofi = fso.OpenTextFile(unversioned, 1);
if (!dryRun) {
of = fso.CreateTextFile(newfile, true);
}
while (ofi.AtEndOfStream !== true) {
ln = ofi.ReadLine();
s = new String(ln);
if (!dryRun && s.search(/\@LIBMODBUS_VERSION_MAJOR\@/) != -1) {
of.WriteLine(s.replace(/\@LIBMODBUS_VERSION_MAJOR\@/, verMajor));
} else if (!dryRun && s.search(/\@LIBMODBUS_VERSION_MINOR\@/) != -1) {
of.WriteLine(s.replace(/\@LIBMODBUS_VERSION_MINOR\@/, verMinor));
} else if (!dryRun && s.search(/\@LIBMODBUS_VERSION_MICRO\@/) != -1) {
of.WriteLine(s.replace(/\@LIBMODBUS_VERSION_MICRO\@/, verMicro));
} else if (!dryRun && s.search(/\@LIBMODBUS_VERSION\@/) != -1) {
of.WriteLine(s.replace(/\@LIBMODBUS_VERSION\@/, verMajor + "." + verMinor + "." + verMicro));
} else {
if (!dryRun) {
of.WriteLine(ln);
}
}
}
ofi.Close();
if (!dryRun) {
of.Close();
}
}
/*
* main(),
* Execution begins here.
*/
// Parse the command-line arguments.
for (i = 0; (i < WScript.Arguments.length) && (error === 0); i++) {
var arg, opt;
arg = WScript.Arguments(i);
opt = arg.substring(0, arg.indexOf("="));
if (opt.length > 0) {
if (opt == "dry-run") {
var str = arg.substring(opt.length + 1, arg.length);
if (opt == 1 || opt == "yes") {
dryRun = true;
}
} else if (opt == "compiler") {
compiler = arg.substring(opt.length + 1, arg.length);
} else {
error = 1;
}
} else if (i === 0) {
if (arg == "help") {
usage();
WScript.Quit(0);
}
} else {
error = 1;
}
}
// If we fail here, it is because the user supplied an unrecognised argument.
if (error !== 0) {
usage();
WScript.Quit(error);
}
// Read the the version.
readVersion();
if (error !== 0) {
WScript.Echo("Version discovery failed, aborting.");
WScript.Quit(error);
}
newfile = srcDir + "\\modbus-version.h";
createVersionedFile(newfile, srcDir + "\\modbus-version.h.in");
if (error !== 0) {
WScript.Echo("Creation of " + newfile + " failed, aborting.");
WScript.Quit(error);
}
newfile = "modbus.dll.manifest";
createVersionedFile(newfile, "modbus.dll.manifest.in");
if (error !== 0) {
WScript.Echo("Creation of " + newfile + " failed, aborting.");
WScript.Quit(error);
}
newfile = "config.h";
createVersionedFile(newfile, "config.h.win32");
if (error !== 0) {
WScript.Echo("Creation of " + newfile + " failed, aborting.");
WScript.Quit(error);
}
WScript.Echo("\nLibmodbus configuration completed\n");

View File

@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "modbus", "modbus.vcproj", "{498E0845-C7F4-438B-8EDE-EF7FC9A74430}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Debug|Win32.ActiveCfg = Debug|Win32
{498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Debug|Win32.Build.0 = Debug|Win32
{498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Release|Win32.ActiveCfg = Release|Win32
{498E0845-C7F4-438B-8EDE-EF7FC9A74430}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="@LIBMODBUS_VERSION@" processorArchitecture="*" name="modbus"/>
<description>Zsh shell</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
</dependency>
</assembly>

View File

@@ -0,0 +1,55 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "config.h"
#include "../modbus-version.h"
#define VERSTRING PACKAGE_VERSION
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION LIBMODBUS_VERSION_MAJOR, LIBMODBUS_VERSION_MINOR, LIBMODBUS_VERSION_MICRO, 2
PRODUCTVERSION LIBMODBUS_VERSION_MAJOR, LIBMODBUS_VERSION_MINOR, LIBMODBUS_VERSION_MICRO, 2
#if defined(DEBUG) || defined(W32DEBUG)
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
{
BLOCK "StringFileInfo"
{
BLOCK "000004E4"
{
VALUE "CompanyName", "\x0"
VALUE "FileDescription", "libmodbus DLL\x0"
#if defined(__MINGW32__) && !defined(__MINGW64__)
VALUE "FileVersion", VERSTRING " (gcc)"
#endif
#if defined(__MINGW64__)
VALUE "FileVersion", VERSTRING " (gcc64)"
#endif
#if defined(_MSC_VER)
# if defined(MSC64)
VALUE "FileVersion", VERSTRING " (cl64)"
# else
VALUE "FileVersion", VERSTRING " (cl)"
# endif
#endif
VALUE "InternalName", "modbus.dll"
VALUE "LegalCopyright", "© See libmodbus.org"
VALUE "OriginalFilename", "modbus.dll"
VALUE "ProductName", "libmodbus"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0, 1252
}
}
// Manifest
#if (_MSC_VER >= 1400)
// CAVEAT: the manifest has a version string THAT MUST MATCH the DLL version
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "modbus.dll.manifest"
#endif

View File

@@ -0,0 +1,457 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="modbus"
ProjectGUID="{498E0845-C7F4-438B-8EDE-EF7FC9A74430}"
RootNamespace="modbus"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
EnableManagedIncrementalBuild="0"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
AdditionalDependencies=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="true"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\src;..;.;D:/include/msvc_std"
PreprocessorDefinitions="W32DEBUG;HAVE_CONFIG_H;DLLBUILD;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NONSTDC_NO_DEPRECATE=1"
MinimalRebuild="false"
ExceptionHandling="0"
BasicRuntimeChecks="2"
RuntimeLibrary="1"
FloatingPointModel="2"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_MSC_VER"
ResourceOutputFileName="$(SolutionDir)/modbus.res"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
Version="1.0.0"
LinkIncremental="1"
AdditionalLibraryDirectories=""
GenerateManifest="true"
GenerateDebugInformation="true"
GenerateMapFile="true"
SubSystem="1"
RandomizedBaseAddress="0"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
EnableManagedIncrementalBuild="0"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
AdditionalDependencies=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\src;..;.;D:/include/msvc_std"
PreprocessorDefinitions="HAVE_CONFIG_H;DLLBUILD;_CRT_SECURE_NO_DEPRECATE=1;_CRT_NONSTDC_NO_DEPRECATE=1"
ExceptionHandling="0"
RuntimeLibrary="0"
EnableFunctionLevelLinking="false"
FloatingPointModel="2"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="0"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions=""
AdditionalDependencies="ws2_32.lib"
LinkIncremental="0"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="1048576"
StackCommitSize="524288"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
EntryPointSymbol=""
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
SuppressStartupBanner="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
AdditionalDependencies=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="$(SolutionDir)"
PreprocessorDefinitions=""
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
DisableSpecificWarnings="4244;4267"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="1048576"
StackCommitSize="524288"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine=""
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
AdditionalDependencies=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="$(SolutionDir)"
PreprocessorDefinitions=""
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
DisableSpecificWarnings="4244;4267"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="1048576"
StackCommitSize="524288"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\modbus-data.c"
>
</File>
<File
RelativePath="..\modbus-rtu.c"
>
</File>
<File
RelativePath="..\modbus-tcp.c"
>
</File>
<File
RelativePath="..\modbus.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="config.h"
>
</File>
<File
RelativePath="..\modbus-private.h"
>
</File>
<File
RelativePath="..\modbus-rtu-private.h"
>
</File>
<File
RelativePath="..\modbus-rtu.h"
>
</File>
<File
RelativePath="..\modbus-tcp-private.h"
>
</File>
<File
RelativePath="..\modbus-tcp.h"
>
</File>
<File
RelativePath="modbus-version.h"
>
</File>
<File
RelativePath="..\modbus.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\modbus.rc"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

25
main.cpp Normal file
View File

@@ -0,0 +1,25 @@
/*
* main.cpp
*
* Created on: Jan 21, 2019
* Author: emanuele
*
* main del software roboglue, si occupa solo dell' inizializzazione delle classi finesta e
* gestore della memoria condivisa
*
* 20190121 - Prima Scittura
*
*/
#include "init/roboglue_init.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
RoboGlue_INIT w;
w.show();
return a.exec();
}

5
main/roboglue_main.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "roboglue_main.h"
RoboGlue_MAIN::RoboGlue_MAIN(RoboGlue_SHARED *mem) {
}

33
main/roboglue_main.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef ROBOGLUE_MAIN_H
#define ROBOGLUE_MAIN_H
/*
* Created on: Jan 22, 2019
* Author: emanuele
*
* MOdulo principale di elaborazione dati che si occupa anche dello scambio dei messaggi tra gli
* altri moduli.
* Per ora le funzioni sono ancora da definire.
*
* 20190122 - Prima Scittura
*/
#include <QThread>
#include <shared/roboglue_shared.h>
class RoboGlue_MAIN : public QThread {
public:
RoboGlue_MAIN(RoboGlue_SHARED *mem);
private:
RoboGlue_SHARED *m;
public slots:
private slots:
signals:
};
#endif // ROBOGLUE_MAIN_H

24
names.json Normal file
View File

@@ -0,0 +1,24 @@
{
"robotModes":{
"-1": "NO_CONTROLLER",
"0" : "DISCONNECTED",
"1" : "CONFIRM_SAFETY",
"2" : "BOOTING",
"3" : "POWER_OFF",
"4" : "POWER_ON",
"5" : "IDLE",
"6" : "BACKDRIVE",
"7" : "RUNNING",
"8" : "UPDATING_FIRMWARE"
},
"controlModes":{
"0":"POSITION",
"1":"TEACH",
"2":"FORCE",
"3":"TORQUE"
},
"booleans":{
"0" : "FALSE",
"1" : "TRUE"
}
}

42
roboglue.conf Normal file
View File

@@ -0,0 +1,42 @@
[gui]
namepath=../RoboGlue/names.json
[init]
autocom=true
autogui=true
automain=false
autotrack=false
[robot]
connection\autoconnect=false
connection\robotip=10.0.0.5
connection\robotport=30002
connection\robotretry=5
kine\dhtable\1\dha=0
kine\dhtable\1\dhalpha=0
kine\dhtable\1\dhd=0
kine\dhtable\1\dhtheta=0
kine\dhtable\2\dha=0
kine\dhtable\2\dhalpha=0
kine\dhtable\2\dhd=0
kine\dhtable\2\dhtheta=0
kine\dhtable\3\dha=0
kine\dhtable\3\dhalpha=0
kine\dhtable\3\dhd=0
kine\dhtable\3\dhtheta=0
kine\dhtable\4\dha=0
kine\dhtable\4\dhalpha=0
kine\dhtable\4\dhd=0
kine\dhtable\4\dhtheta=0
kine\dhtable\5\dha=0
kine\dhtable\5\dhalpha=0
kine\dhtable\5\dhd=0
kine\dhtable\5\dhtheta=0
kine\dhtable\6\dha=0
kine\dhtable\6\dhalpha=0
kine\dhtable\6\dhd=0
kine\dhtable\6\dhtheta=0
kine\dhtable\size=6
kine\maxreach=@Variant(\0\0\0\x87?\x99\x99\x9a)
kine\prefix=0
kine\suffix=0

0
roboglue_comROS.cpp Normal file
View File

5
roboglue_resources.qrc Normal file
View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/images">
<file>PiantaRobot_Alto.png</file>
</qresource>
</RCC>

113
shared/roboglue_shared.cpp Normal file
View File

@@ -0,0 +1,113 @@
#include "roboglue_shared.h"
RoboGlue_SHARED::RoboGlue_SHARED(QSettings *set){
settings=set;
robotVariables.insert(std::pair<std::string, int>("RDY",1));
}
////////////////////////////////////////////////////////////////
/////////////////////// RESTORE FUNCTIONS /////////////////////
/////////////////////////////////////////////////////////////
void RoboGlue_SHARED::restoreInitSettings(){
settings->beginGroup("init");
initSettings.size=settings->value("size").toSize();
initSettings.pos=settings->value("pos").toPoint();
initSettings.autoMain=settings->value("automain").toBool();
initSettings.autoCom=settings->value("autocom").toBool();
initSettings.autoTrack=settings->value("autotrack").toBool();
initSettings.autoGui=settings->value("autogui").toBool();
settings->endGroup();
}
void RoboGlue_SHARED::restoreComSettings() {
settings->beginGroup("robot");
// connection parameters
settings->beginGroup("connection");
comSettings.connection.robotIp=settings->value("robotip").toString().toStdString();
comSettings.connection.robotPort=settings->value("robotport").toUInt();
comSettings.connection.retry=static_cast<uchar>(settings->value("robotretry").toUInt());
comSettings.connection.autoConnect=settings->value("autoconnect").toBool();
comSettings.connection.prefix=settings->value("prefix").toChar().toLatin1();
comSettings.connection.suffix=settings->value("suffix").toChar().toLatin1();
settings->endGroup();
// kinematic parameters
settings->beginGroup("kine");
int ksize=settings->beginReadArray("dhtable");
for(int i=0; i<ksize; i++){
settings->setArrayIndex(i);
comSettings.kine.DHtable.DHa[i] = settings->value("dha").toDouble();
comSettings.kine.DHtable.DHd[i] = settings->value("dhd").toDouble();
comSettings.kine.DHtable.DHalpha[i] = settings->value("dhaplha").toDouble();
comSettings.kine.DHtable.DHtheta[i] = settings->value("dhtheta").toDouble();
}
settings->endArray();
comSettings.kine.maxReach = settings->value("maxreach").toFloat();
settings->endGroup();
// exchange variables
settings->beginGroup("variables");
// TODO something
settings->endGroup();
settings->endGroup();
}
void RoboGlue_SHARED::restoreGuiSettings() {
settings->beginGroup("gui");
guiSettings.namePath=settings->value("namepath").toString().toStdString();
settings->endGroup();
}
void RoboGlue_SHARED::restoreMainSettings() {
settings->beginGroup("main");
settings->endGroup();
}
void RoboGlue_SHARED::restoreTrackSettings() {
settings->beginGroup("track");
settings->endGroup();
}
////////////////////////////////////////////////////////////////
/////////////////////// SAVE FUNCTIONS ////////////////////////
//////////////////////////////////////////////////////////////
void RoboGlue_SHARED::saveCommonSettings(){
settings->beginGroup("common");
settings->endGroup();
}
void RoboGlue_SHARED::saveInitSettings() {
settings->beginGroup("init");
settings->setValue("autocom",initSettings.autoCom);
settings->setValue("autogui",initSettings.autoGui);
settings->setValue("autotrack",initSettings.autoTrack);
settings->setValue("automain",initSettings.autoMain);
settings->endGroup();
}
void RoboGlue_SHARED::saveComSettings() {
settings->beginGroup("robot");
settings->beginGroup("kine");
settings->setValue("maxreach", comSettings.kine.maxReach);
settings->setValue("prefix", comSettings.connection.prefix);
settings->setValue("suffix", comSettings.connection.suffix);
settings->endGroup();
settings->endGroup();
}
void RoboGlue_SHARED::saveGuiSettings() {
settings->beginGroup("gui");
settings->setValue("namepath", QString(guiSettings.namePath.c_str()));
settings->endGroup();
}
void RoboGlue_SHARED::saveMainSettings() {
settings->beginGroup("main");
settings->endGroup();
}
void RoboGlue_SHARED::saveTrackSettings() {
settings->beginGroup("track");
settings->endGroup();
}

129
shared/roboglue_shared.h Normal file
View File

@@ -0,0 +1,129 @@
#ifndef ROBOGLUE_SHARED_H
#define ROBOGLUE_SHARED_H
/*
* Created on: Jan 22, 2019
* Author: emanuele
*
* Modulo di memoria condivisa tra i thread per lo scambio di strutture dati che non è permesso
* nell'invio di segnali.
* Conterrà anche le funzioni che si occupano di salvare e ripristinare le configurazioni del software.
*
* 20190122 - Prima Scittura
* 20190123 - Implementate le funzioni che leggono il file di configurazione e ripristinano
* le impostazioni ad ogni avvio.
* Le impostazioni persistenti sono raggruppate in strutture accessibili ai vari moduli.
* le funzioni in questa classe si occupano solo di ripristinare i valori salvati
* ogni modulo è responsabile di aggiornare i valori nella sua struttra e nel file
* di configurazione che viene salvato alla chiusura del programma.
* Questo perchè gli eventi che modificano le configurazioni sono molteplici e sparsi in
* tutti i moduli
* QUESTA COSA VA GIÀ CAMBIATA PERCHÈ È TROPPO CONFUSIONARIA!!
* 20190124 - Implementati tutti i metodi che salvano e ripristinano le configurazioni.
* 20190311 - Aggiunta la struttura che tiene gli stati che devono rimanere comuni ai moduli.
*
*/
#include <QMutex>
#include <QSettings>
#include <QPoint>
#include <QSize>
#include <stdexcept>
#include <libJson/json.hpp>
#include <libURcom/URCLinterface.h>
using namespace nlohmann;
class RoboGlue_SHARED : public QObject{
Q_OBJECT
public:
RoboGlue_SHARED(QSettings *set);
QMutex mutex;
//////////// COMMON MODULES STATUS ///////////////
struct {
bool isRecording = false;
bool isPlaying = false;
bool isRealtime = false;
bool isFileOpen = false;
} commonStatus;
/////////// PERMANENT SETTINGS VARIABLES /////////
struct{
json baseMessage;
} commonSettings;
struct {
QPoint pos;
QSize size;
std::string version;
bool autoMain;
bool autoGui;
bool autoTrack;
bool autoCom;
} initSettings;
struct {
struct {
std::string robotIp = std::string("192.168.0.31");
uint robotPort = 30002;
unsigned char retry = 5;
bool autoConnect = false;
char prefix = '{';
char suffix = '}';
} connection;
struct{
kineDH_t DHtable;
float maxReach = 1.2;
} kine;
std::vector<std::string> subList {
{"roboglue_com/ros2com/commands"},
{"roboglue_com/ros2com/coordinates"},
{"roboglue_com/ros2com/state"}
};
std::vector<std::string> pubList {
{"roboglue_com/com2ros/commands"},
{"roboglue_com/com2ros/coordinates"},
{"roboglue_com/com2ros/state"}
};
enum {
COMM, COORD, STAT
} tList;
} comSettings;
struct {
std::string namePath = "../RoboGlue/names.json";
} guiSettings;
struct {
} mainSettings;
struct {
} trackSettings;
QSettings *settings;
clientData_t robotData;
std::map<std::string,int> robotVariables;
void restoreCommonSettings();
void restoreInitSettings();
void restoreComSettings();
void restoreGuiSettings();
void restoreMainSettings();
void restoreTrackSettings();
void saveCommonSettings();
void saveInitSettings();
void saveComSettings();
void saveGuiSettings();
void saveMainSettings();
void saveTrackSettings();
signals:
void commonStatusChange(void);
};
#endif // ROBOGLUE_SHARED_H

5
track/roboglue_track.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "roboglue_track.h"
RoboGlue_TRACK::RoboGlue_TRACK(RoboGlue_SHARED *mem) {
}

31
track/roboglue_track.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef ROBOGLUE_TRACK_H
#define ROBOGLUE_TRACK_H
/*
* Created on: Jan 22, 2019
* Author: emanuele
*
* Modulo che si occupa della gestione del tracker 3D, funzioni e implementazione ancora da definire
*
* 20190122 - Prima Scittura
*/
#include <QThread>
#include <shared/roboglue_shared.h>
class RoboGlue_TRACK : public QThread {
public:
RoboGlue_TRACK(RoboGlue_SHARED *mem) ;
private:
RoboGlue_SHARED *m;
public slots:
private slots:
signals:
};
#endif // ROBOGLUE_TRACK_H