diff --git a/build.ps1 b/build.ps1
index aa68889..0cf4480 100644
--- a/build.ps1
+++ b/build.ps1
@@ -43,18 +43,17 @@ if($standalone) {
& "$scriptPath\src\ros2cs\build.ps1" @options
if($?) {
- md -Force $scriptPath\install\asset | Out-Null
- Copy-Item -Path $scriptPath\src\Ros2ForUnity -Destination $scriptPath\install\asset\ -Recurse -Force
+ md -Force $scriptPath\install\package | Out-Null
+ Copy-Item -Path $scriptPath\src\Ros2ForUnity -Destination $scriptPath\install\package\ -Recurse -Force
- $plugin_path=Join-Path -Path $scriptPath -ChildPath "\install\asset\Ros2ForUnity\Plugins\"
+ $plugin_path=Join-Path -Path $scriptPath -ChildPath "\install\package\Ros2ForUnity\Runtime\Plugins\"
Write-Host "Deploying build to $plugin_path" -ForegroundColor Green
& "$scriptPath\deploy_unity_plugins.ps1" $plugin_path
- Copy-Item -Path $scriptPath\src\Ros2ForUnity\metadata_ros2cs.xml -Destination $scriptPath\install\asset\Ros2ForUnity\Plugins\Windows\x86_64\
- Copy-Item -Path $scriptPath\src\Ros2ForUnity\metadata_ros2cs.xml -Destination $scriptPath\install\asset\Ros2ForUnity\Plugins\
+ Copy-Item -Path $scriptPath\src\Ros2ForUnity\Runtime\metadata_ros2cs.xml -Destination $scriptPath\install\package\Ros2ForUnity\Runtime\Plugins\Windows\x86_64\
+ Copy-Item -Path $scriptPath\src\Ros2ForUnity\Runtime\metadata_ros2cs.xml -Destination $scriptPath\install\package\Ros2ForUnity\Runtime\Plugins\
+ Copy-Item -Path $scriptPath\README.md -Destination $scriptPath\install\package\Ros2ForUnity\
} else {
Write-Host "Ros2cs build failed!" -ForegroundColor Red
exit 1
}
-
-
diff --git a/src/Ros2ForUnity/Runtime.meta b/src/Ros2ForUnity/Runtime.meta
new file mode 100644
index 0000000..13c9309
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 13a1b243ce6b36e4196ef79619f7b40a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Plugins.meta b/src/Ros2ForUnity/Runtime/Plugins.meta
similarity index 77%
rename from src/Ros2ForUnity/Plugins.meta
rename to src/Ros2ForUnity/Runtime/Plugins.meta
index f77a550..aa81df9 100644
--- a/src/Ros2ForUnity/Plugins.meta
+++ b/src/Ros2ForUnity/Runtime/Plugins.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 79b46a636d96b67468a29e597cb7b06a
+guid: 131987f734e4d9f439acfef5ccb677c0
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/src/Ros2ForUnity/Plugins/.gitkeep b/src/Ros2ForUnity/Runtime/Plugins/.gitkeep
similarity index 100%
rename from src/Ros2ForUnity/Plugins/.gitkeep
rename to src/Ros2ForUnity/Runtime/Plugins/.gitkeep
diff --git a/src/Ros2ForUnity/Scripts.meta b/src/Ros2ForUnity/Runtime/Scripts.meta
similarity index 77%
rename from src/Ros2ForUnity/Scripts.meta
rename to src/Ros2ForUnity/Runtime/Scripts.meta
index fb3bbc9..fd068c8 100644
--- a/src/Ros2ForUnity/Scripts.meta
+++ b/src/Ros2ForUnity/Runtime/Scripts.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: f750980d49c8bcf39830e89365689d16
+guid: e0bf4f692fdb2bb44aed07a15bc7b16c
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/src/Ros2ForUnity/Scripts/PostInstall.cs b/src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs
similarity index 69%
rename from src/Ros2ForUnity/Scripts/PostInstall.cs
rename to src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs
index 2f4dd03..55f0879 100644
--- a/src/Ros2ForUnity/Scripts/PostInstall.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs
@@ -33,20 +33,24 @@ public void OnPostprocessBuild(BuildReport report)
var r2fuMetadataName = "metadata_ros2_for_unity.xml";
var r2csMetadataName = "metadata_ros2cs.xml";
- // FileUtil.CopyFileOrDirectory: All file separators should be forward ones "/".
- var r2fuMeta = ROS2ForUnity.GetRos2ForUnityPath() + "/" + r2fuMetadataName;
- var r2csMeta = ROS2ForUnity.GetPluginPath() + "/" + r2csMetadataName;
- var outputDir = Directory.GetParent(report.summary.outputPath);
+ var r2fuMeta = Path.Combine(ROS2ForUnity.rootPath, r2fuMetadataName);
+ var r2csMeta = Path.Combine(ROS2ForUnity.pluginPath, r2csMetadataName);
+
+ var outputDir = Directory.GetParent(report.summary.outputPath).ToString();
var execFilename = Path.GetFileNameWithoutExtension(report.summary.outputPath);
+
FileUtil.CopyFileOrDirectory(
- r2fuMeta, outputDir + "/" + execFilename + "_Data/" + r2fuMetadataName);
+ r2fuMeta, Path.Combine(outputDir, execFilename + "_Data", r2fuMetadataName)
+ );
+
+ string r2csMetaTarget;
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneLinux64) {
- FileUtil.CopyFileOrDirectory(
- r2csMeta, outputDir + "/" + execFilename + "_Data/Plugins/" + r2csMetadataName);
+ r2csMetaTarget = Path.Combine(outputDir, execFilename + "_Data", "Plugins", r2csMetadataName);
} else {
- FileUtil.CopyFileOrDirectory(
- r2csMeta, outputDir + "/" + execFilename + "_Data/Plugins/x86_64/" + r2csMetadataName);
+ r2csMetaTarget = Path.Combine(outputDir, execFilename + "_Data", "Plugins", "x86_64", r2csMetadataName);
}
+
+ FileUtil.CopyFileOrDirectory(r2csMeta, r2csMetaTarget);
}
}
diff --git a/src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs.meta
new file mode 100644
index 0000000..fc5a57f
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/PostInstall.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 58c6e966dff4d9f49b70ece3620a65ab
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/ROS2ClientExample.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2ClientExample.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2ClientExample.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ClientExample.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/ROS2ClientExample.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2ClientExample.cs.meta
new file mode 100644
index 0000000..365ebbf
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2ClientExample.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bbecdb758cb91d74585785bc4ed52555
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/ROS2ForUnity.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2ForUnity.cs
similarity index 84%
rename from src/Ros2ForUnity/Scripts/ROS2ForUnity.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ForUnity.cs
index 4ba7cfd..999356c 100644
--- a/src/Ros2ForUnity/Scripts/ROS2ForUnity.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2ForUnity.cs
@@ -1,372 +1,357 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEditor;
-using System.Xml;
-
-namespace ROS2
-{
-
-///
-/// An internal class responsible for handling checking, proper initialization and shutdown of ROS2cs,
-///
-internal class ROS2ForUnity
-{
- private static bool isInitialized = false;
- private static string ros2ForUnityAssetFolderName = "Ros2ForUnity";
- private XmlDocument ros2csMetadata = new XmlDocument();
- private XmlDocument ros2ForUnityMetadata = new XmlDocument();
-
- public enum Platform
- {
- Windows,
- Linux
- }
-
- public static Platform GetOS()
- {
- if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer)
- {
- return Platform.Linux;
- }
- else if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
- {
- return Platform.Windows;
- }
- throw new System.NotSupportedException("Only Linux and Windows are supported");
- }
-
- private static bool InEditor() {
- return Application.isEditor;
- }
-
- private static string GetOSName()
- {
- switch (GetOS())
- {
- case Platform.Linux:
- return "Linux";
- case Platform.Windows:
- return "Windows";
- default:
- throw new System.NotSupportedException("Only Linux and Windows are supported");
- }
- }
-
- private string GetEnvPathVariableName()
- {
- string envVariable = "LD_LIBRARY_PATH";
- if (GetOS() == Platform.Windows)
- {
- envVariable = "PATH";
- }
- return envVariable;
- }
-
- private string GetEnvPathVariableValue()
- {
- return Environment.GetEnvironmentVariable(GetEnvPathVariableName());
- }
-
- public static string GetRos2ForUnityPath()
- {
- char separator = Path.DirectorySeparatorChar;
- string appDataPath = Application.dataPath;
- string pluginPath = appDataPath;
-
- if (InEditor()) {
- pluginPath += separator + ros2ForUnityAssetFolderName;
- }
- return pluginPath;
- }
-
- public static string GetPluginPath()
- {
- char separator = Path.DirectorySeparatorChar;
- string ros2ForUnityPath = GetRos2ForUnityPath();
- string pluginPath = ros2ForUnityPath;
-
- pluginPath += separator + "Plugins";
-
- if (InEditor()) {
- pluginPath += separator + GetOSName();
- }
-
- if (InEditor() || GetOS() == Platform.Windows)
- {
- pluginPath += separator + "x86_64";
- }
-
- if (GetOS() == Platform.Windows)
- {
- pluginPath = pluginPath.Replace("/", "\\");
- }
-
- return pluginPath;
- }
-
- ///
- /// Function responsible for setting up of environment paths for standalone builds
- ///
- ///
- /// Note that on Linux, LD_LIBRARY_PATH as used for dlopen() is determined on process start and this change won't
- /// affect it. Ros2 looks for rmw implementation based on this variable (independently) and the change
- /// is effective for this process, however rmw implementation's dependencies itself are loaded by dynamic linker
- /// anyway so setting it for Linux is pointless.
- ///
- private void SetEnvPathVariable()
- {
- string currentPath = GetEnvPathVariableValue();
- string pluginPath = GetPluginPath();
-
- char envPathSep = ':';
- if (GetOS() == Platform.Windows)
- {
- envPathSep = ';';
- }
-
- Environment.SetEnvironmentVariable(GetEnvPathVariableName(), pluginPath + envPathSep + currentPath);
- }
-
- public bool IsStandalone() {
- return Convert.ToBoolean(Convert.ToInt16(GetMetadataValue(ros2csMetadata, "/ros2cs/standalone")));
- }
-
- public string GetROSVersion()
- {
- string ros2SourcedCodename = GetROSVersionSourced();
- string ros2FromRos4UMetadata = GetMetadataValue(ros2ForUnityMetadata, "/ros2_for_unity/ros2");
-
- // Sourced ROS2 libs takes priority
- if (string.IsNullOrEmpty(ros2SourcedCodename)) {
- return ros2FromRos4UMetadata;
- }
-
- return ros2SourcedCodename;
- }
-
- ///
- /// Checks if both ros2cs and ros2-for-unity were build for the same ros version as well as
- /// the current sourced ros version matches ros2cs binaries.
- ///
- public void CheckIntegrity()
- {
- string ros2SourcedCodename = GetROSVersionSourced();
- string ros2FromRos2csMetadata = GetMetadataValue(ros2csMetadata, "/ros2cs/ros2");
- string ros2FromRos4UMetadata = GetMetadataValue(ros2ForUnityMetadata, "/ros2_for_unity/ros2");
-
- if (ros2FromRos4UMetadata != ros2FromRos2csMetadata) {
- Debug.LogError(
- "ROS2 versions in 'ros2cs' and 'ros2-for-unity' metadata files are not the same. " +
- "This is caused by mixing versions/builds. Plugin might not work correctly."
- );
- }
-
- if(!IsStandalone() && ros2SourcedCodename != ros2FromRos2csMetadata) {
- Debug.LogError(
- "ROS2 version in 'ros2cs' metadata doesn't match currently sourced version. " +
- "This is caused by mixing versions/builds. Plugin might not work correctly."
- );
- }
-
- if (IsStandalone() && !string.IsNullOrEmpty(ros2SourcedCodename)) {
- Debug.LogError(
- "You should not source ROS2 in 'ros2-for-unity' standalone build. " +
- "Plugin might not work correctly."
- );
- }
- }
-
- public string GetROSVersionSourced()
- {
- return Environment.GetEnvironmentVariable("ROS_DISTRO");
- }
-
- ///
- /// Check if the ros version is supported, only applicable to non-standalone plugin versions
- /// (i. e. without ros2 libraries included in the plugin).
- ///
- private void CheckROSSupport(string ros2Codename)
- {
- List supportedVersions = new List() { "foxy", "galactic", "humble", "rolling" };
- var supportedVersionsString = String.Join(", ", supportedVersions);
- if (string.IsNullOrEmpty(ros2Codename))
- {
- string errMessage = "No ROS environment sourced. You need to source your ROS2 " + supportedVersionsString
- + " environment before launching Unity (ROS_DISTRO env variable not found)";
- Debug.LogError(errMessage);
-#if UNITY_EDITOR
- EditorApplication.isPlaying = false;
- throw new System.InvalidOperationException(errMessage);
-#else
- const int ROS_NOT_SOURCED_ERROR_CODE = 33;
- Application.Quit(ROS_NOT_SOURCED_ERROR_CODE);
-#endif
- }
-
- if (!supportedVersions.Contains(ros2Codename))
- {
- string errMessage = "Currently sourced ROS version differs from supported one. Sourced: " + ros2Codename
- + ", supported: " + supportedVersionsString + ".";
- Debug.LogError(errMessage);
-#if UNITY_EDITOR
- EditorApplication.isPlaying = false;
- throw new System.NotSupportedException(errMessage);
-#else
- const int ROS_BAD_VERSION_CODE = 34;
- Application.Quit(ROS_BAD_VERSION_CODE);
-#endif
- } else if (ros2Codename.Equals("rolling") ) {
- Debug.LogWarning("You are using ROS2 rolling version. Bleeding edge version might not work correctly.");
- }
- }
-
- private void RegisterCtrlCHandler()
- {
-#if ENABLE_MONO
- // Il2CPP build does not support Console.CancelKeyPress currently
- Console.CancelKeyPress += (sender, eventArgs) => {
- eventArgs.Cancel = true;
- DestroyROS2ForUnity();
- };
-#endif
- }
-
- private void ConnectLoggers()
- {
- Ros2csLogger.setCallback(LogLevel.ERROR, Debug.LogError);
- Ros2csLogger.setCallback(LogLevel.WARNING, Debug.LogWarning);
- Ros2csLogger.setCallback(LogLevel.INFO, Debug.Log);
- Ros2csLogger.setCallback(LogLevel.DEBUG, Debug.Log);
- Ros2csLogger.LogLevel = LogLevel.WARNING;
- }
-
- private string GetMetadataValue(XmlDocument doc, string valuePath)
- {
- return doc.DocumentElement.SelectSingleNode(valuePath).InnerText;
- }
-
- private void LoadMetadata()
- {
- char separator = Path.DirectorySeparatorChar;
- try
- {
- ros2csMetadata.Load(GetPluginPath() + separator + "metadata_ros2cs.xml");
- ros2ForUnityMetadata.Load(GetRos2ForUnityPath() + separator + "metadata_ros2_for_unity.xml");
- }
- catch (System.IO.FileNotFoundException)
- {
-#if UNITY_EDITOR
- var errMessage = "Could not find metadata files.";
- EditorApplication.isPlaying = false;
- throw new System.IO.FileNotFoundException(errMessage);
-#else
- const int NO_METADATA = 1;
- Application.Quit(NO_METADATA);
-#endif
- }
- }
-
- internal ROS2ForUnity()
- {
- // Load metadata
- LoadMetadata();
- string currentRos2Version = GetROSVersion();
- string standalone = IsStandalone() ? "standalone" : "non-standalone";
-
- // Self checks
- CheckROSSupport(currentRos2Version);
- CheckIntegrity();
-
- // Library loading
- if (GetOS() == Platform.Windows) {
- // Windows version can run standalone, modifies PATH to ensure all plugins visibility
- SetEnvPathVariable();
- } else {
- // For foxy, it is necessary to use modified version of librcpputils to resolve custom msgs packages.
- ROS2.GlobalVariables.absolutePath = GetPluginPath() + "/";
- if (currentRos2Version == "foxy") {
- ROS2.GlobalVariables.preloadLibrary = true;
- ROS2.GlobalVariables.preloadLibraryName = "librcpputils.so";
- }
- }
-
- // Initialize
- ConnectLoggers();
- Ros2cs.Init();
- RegisterCtrlCHandler();
-
- string rmwImpl = Ros2cs.GetRMWImplementation();
-
- Debug.Log("ROS2 version: " + currentRos2Version + ". Build type: " + standalone + ". RMW: " + rmwImpl);
-
-#if UNITY_EDITOR
- EditorApplication.playModeStateChanged += this.EditorPlayStateChanged;
- EditorApplication.quitting += this.DestroyROS2ForUnity;
-#endif
- isInitialized = true;
- }
-
- private static void ThrowIfUninitialized(string callContext)
- {
- if (!isInitialized)
- {
- throw new InvalidOperationException("Ros2 For Unity is not initialized, can't " + callContext);
- }
- }
-
- ///
- /// Check if ROS2 module is properly initialized and no shutdown was called yet
- ///
- /// The state of ROS2 module. Should be checked before attempting to create or use pubs/subs
- public bool Ok()
- {
- if (!isInitialized)
- {
- return false;
- }
- return Ros2cs.Ok();
- }
-
- internal void DestroyROS2ForUnity()
- {
- if (isInitialized)
- {
- Debug.Log("Shutting down Ros2 For Unity");
- Ros2cs.Shutdown();
- isInitialized = false;
- }
- }
-
- ~ROS2ForUnity()
- {
- DestroyROS2ForUnity();
- }
-
-#if UNITY_EDITOR
- void EditorPlayStateChanged(PlayModeStateChange change)
- {
- if (change == PlayModeStateChange.ExitingPlayMode)
- {
- DestroyROS2ForUnity();
- }
- }
-#endif
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using System.Xml;
+
+namespace ROS2
+{
+
+///
+/// An internal class responsible for handling checking, proper initialization and shutdown of ROS2cs,
+///
+internal class ROS2ForUnity
+{
+ private static bool isInitialized = false;
+ private static string ros2ForUnityAssetFolderName = "Ros2ForUnity";
+ public readonly static string rootPath; // Full path to `Runtime/`
+ public readonly static string pluginPath; // Full path to `Runtime/Plugins/[Platform]/`
+ private XmlDocument ros2csMetadata = new XmlDocument();
+ private XmlDocument ros2ForUnityMetadata = new XmlDocument();
+
+ public enum Platform
+ {
+ Windows,
+ Linux
+ }
+
+ public static Platform GetOS()
+ {
+ if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer)
+ {
+ return Platform.Linux;
+ }
+ else if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
+ {
+ return Platform.Windows;
+ }
+ throw new System.NotSupportedException("Only Linux and Windows are supported");
+ }
+
+ private static bool InEditor() {
+ return Application.isEditor;
+ }
+
+ private static string GetOSName()
+ {
+ switch (GetOS())
+ {
+ case Platform.Linux:
+ return "Linux";
+ case Platform.Windows:
+ return "Windows";
+ default:
+ throw new System.NotSupportedException("Only Linux and Windows are supported");
+ }
+ }
+
+ private string GetEnvPathVariableName()
+ {
+ if (GetOS() == Platform.Windows)
+ {
+ return "PATH";
+ }
+
+ return "LD_LIBRARY_PATH";
+ }
+
+ private string GetEnvPathVariableValue()
+ {
+ return Environment.GetEnvironmentVariable(GetEnvPathVariableName());
+ }
+
+ ///
+ /// Function responsible for setting up of environment paths for standalone builds
+ ///
+ ///
+ /// Note that on Linux, LD_LIBRARY_PATH as used for dlopen() is determined on process start and this change won't
+ /// affect it. Ros2 looks for rmw implementation based on this variable (independently) and the change
+ /// is effective for this process, however rmw implementation's dependencies itself are loaded by dynamic linker
+ /// anyway so setting it for Linux is pointless.
+ ///
+ private void SetEnvPathVariable()
+ {
+ string currentPath = GetEnvPathVariableValue();
+
+ char envPathSep = (GetOS() == Platform.Windows) ? ';' : ':';
+
+ Environment.SetEnvironmentVariable(GetEnvPathVariableName(), pluginPath + envPathSep + currentPath);
+ }
+
+ public bool IsStandalone() {
+ return Convert.ToBoolean(Convert.ToInt16(GetMetadataValue(ros2csMetadata, "/ros2cs/standalone")));
+ }
+
+ public string GetROSVersion()
+ {
+ string ros2SourcedCodename = GetROSVersionSourced();
+ string ros2FromRos4UMetadata = GetMetadataValue(ros2ForUnityMetadata, "/ros2_for_unity/ros2");
+
+ // Sourced ROS2 libs takes priority
+ if (string.IsNullOrEmpty(ros2SourcedCodename)) {
+ return ros2FromRos4UMetadata;
+ }
+
+ return ros2SourcedCodename;
+ }
+
+ ///
+ /// Checks if both ros2cs and ros2-for-unity were build for the same ros version as well as
+ /// the current sourced ros version matches ros2cs binaries.
+ ///
+ public void CheckIntegrity()
+ {
+ string ros2SourcedCodename = GetROSVersionSourced();
+ string ros2FromRos2csMetadata = GetMetadataValue(ros2csMetadata, "/ros2cs/ros2");
+ string ros2FromRos4UMetadata = GetMetadataValue(ros2ForUnityMetadata, "/ros2_for_unity/ros2");
+
+ if (ros2FromRos4UMetadata != ros2FromRos2csMetadata) {
+ Debug.LogError(
+ "ROS2 versions in 'ros2cs' and 'ros2-for-unity' metadata files are not the same. " +
+ "This is caused by mixing versions/builds. Plugin might not work correctly."
+ );
+ }
+
+ if(!IsStandalone() && ros2SourcedCodename != ros2FromRos2csMetadata) {
+ Debug.LogError(
+ "ROS2 version in 'ros2cs' metadata doesn't match currently sourced version. " +
+ "This is caused by mixing versions/builds. Plugin might not work correctly."
+ );
+ }
+
+ if (IsStandalone() && !string.IsNullOrEmpty(ros2SourcedCodename)) {
+ Debug.LogError(
+ "You should not source ROS2 in 'ros2-for-unity' standalone build. " +
+ "Plugin might not work correctly."
+ );
+ }
+ }
+
+ public string GetROSVersionSourced()
+ {
+ return Environment.GetEnvironmentVariable("ROS_DISTRO");
+ }
+
+ ///
+ /// Check if the ros version is supported, only applicable to non-standalone plugin versions
+ /// (i. e. without ros2 libraries included in the plugin).
+ ///
+ private void CheckROSSupport(string ros2Codename)
+ {
+ List supportedVersions = new List() { "foxy", "galactic", "humble", "rolling" };
+ var supportedVersionsString = String.Join(", ", supportedVersions);
+ if (string.IsNullOrEmpty(ros2Codename))
+ {
+ string errMessage = "No ROS environment sourced. You need to source your ROS2 " + supportedVersionsString
+ + " environment before launching Unity (ROS_DISTRO env variable not found)";
+ Debug.LogError(errMessage);
+#if UNITY_EDITOR
+ EditorApplication.isPlaying = false;
+ throw new System.InvalidOperationException(errMessage);
+#else
+ const int ROS_NOT_SOURCED_ERROR_CODE = 33;
+ Application.Quit(ROS_NOT_SOURCED_ERROR_CODE);
+#endif
+ }
+
+ if (!supportedVersions.Contains(ros2Codename))
+ {
+ string errMessage = "Currently sourced ROS version differs from supported one. Sourced: " + ros2Codename
+ + ", supported: " + supportedVersionsString + ".";
+ Debug.LogError(errMessage);
+#if UNITY_EDITOR
+ EditorApplication.isPlaying = false;
+ throw new System.NotSupportedException(errMessage);
+#else
+ const int ROS_BAD_VERSION_CODE = 34;
+ Application.Quit(ROS_BAD_VERSION_CODE);
+#endif
+ } else if (ros2Codename.Equals("rolling") ) {
+ Debug.LogWarning("You are using ROS2 rolling version. Bleeding edge version might not work correctly.");
+ }
+ }
+
+ private void RegisterCtrlCHandler()
+ {
+#if ENABLE_MONO
+ // Il2CPP build does not support Console.CancelKeyPress currently
+ Console.CancelKeyPress += (sender, eventArgs) => {
+ eventArgs.Cancel = true;
+ DestroyROS2ForUnity();
+ };
+#endif
+ }
+
+ private void ConnectLoggers()
+ {
+ Ros2csLogger.setCallback(LogLevel.ERROR, Debug.LogError);
+ Ros2csLogger.setCallback(LogLevel.WARNING, Debug.LogWarning);
+ Ros2csLogger.setCallback(LogLevel.INFO, Debug.Log);
+ Ros2csLogger.setCallback(LogLevel.DEBUG, Debug.Log);
+ Ros2csLogger.LogLevel = LogLevel.WARNING;
+ }
+
+ private string GetMetadataValue(XmlDocument doc, string valuePath)
+ {
+ return doc.DocumentElement.SelectSingleNode(valuePath).InnerText;
+ }
+
+ private void LoadMetadata()
+ {
+ try
+ {
+ ros2csMetadata.Load(
+ Path.Combine(pluginPath, "metadata_ros2cs.xml")
+ );
+ ros2ForUnityMetadata.Load(
+ Path.Combine(rootPath, "metadata_ros2_for_unity.xml")
+ );
+ }
+ catch (System.IO.FileNotFoundException)
+ {
+#if UNITY_EDITOR
+ var errMessage = "Could not find metadata files.";
+ EditorApplication.isPlaying = false;
+ throw new System.IO.FileNotFoundException(errMessage);
+#else
+ const int NO_METADATA = 1;
+ Application.Quit(NO_METADATA);
+#endif
+ }
+ }
+
+ ///
+ /// Static constructor (mostly for paths)
+ ///
+ static ROS2ForUnity()
+ {
+ // Make paths:
+
+ rootPath = Path.GetFullPath("Packages/com.robotecai.ros2-for-unity/Runtime");
+
+ pluginPath = Path.Combine(rootPath, "Plugins");
+
+ if (InEditor())
+ {
+ pluginPath = Path.Combine(pluginPath, GetOSName());
+ }
+
+ if (InEditor() || GetOS() == Platform.Windows)
+ {
+ pluginPath = Path.Combine(pluginPath, "x86_64");
+ }
+ }
+
+ internal ROS2ForUnity()
+ {
+ // Load metadata
+ LoadMetadata();
+ string currentRos2Version = GetROSVersion();
+ string standalone = IsStandalone() ? "standalone" : "non-standalone";
+
+ // Self checks
+ CheckROSSupport(currentRos2Version);
+ CheckIntegrity();
+
+ // Library loading
+ if (GetOS() == Platform.Windows) {
+ // Windows version can run standalone, modifies PATH to ensure all plugins visibility
+ SetEnvPathVariable();
+ } else {
+ // For foxy, it is necessary to use modified version of librcpputils to resolve custom msgs packages.
+ ROS2.GlobalVariables.absolutePath = pluginPath + Path.PathSeparator;
+ if (currentRos2Version == "foxy") {
+ ROS2.GlobalVariables.preloadLibrary = true;
+ ROS2.GlobalVariables.preloadLibraryName = "librcpputils.so";
+ }
+ }
+
+ // Initialize
+ ConnectLoggers();
+ Ros2cs.Init();
+ RegisterCtrlCHandler();
+
+ string rmwImpl = Ros2cs.GetRMWImplementation();
+
+ Debug.Log("ROS2 version: " + currentRos2Version + ". Build type: " + standalone + ". RMW: " + rmwImpl);
+
+#if UNITY_EDITOR
+ EditorApplication.playModeStateChanged += this.EditorPlayStateChanged;
+ EditorApplication.quitting += this.DestroyROS2ForUnity;
+#endif
+ isInitialized = true;
+ }
+
+ private static void ThrowIfUninitialized(string callContext)
+ {
+ if (!isInitialized)
+ {
+ throw new InvalidOperationException("Ros2 For Unity is not initialized, can't " + callContext);
+ }
+ }
+
+ ///
+ /// Check if ROS2 module is properly initialized and no shutdown was called yet
+ ///
+ /// The state of ROS2 module. Should be checked before attempting to create or use pubs/subs
+ public bool Ok()
+ {
+ if (!isInitialized)
+ {
+ return false;
+ }
+ return Ros2cs.Ok();
+ }
+
+ internal void DestroyROS2ForUnity()
+ {
+ if (isInitialized)
+ {
+ Debug.Log("Shutting down Ros2 For Unity");
+ Ros2cs.Shutdown();
+ isInitialized = false;
+ }
+ }
+
+ ~ROS2ForUnity()
+ {
+ DestroyROS2ForUnity();
+ }
+
+#if UNITY_EDITOR
+ void EditorPlayStateChanged(PlayModeStateChange change)
+ {
+ if (change == PlayModeStateChange.ExitingPlayMode)
+ {
+ DestroyROS2ForUnity();
+ }
+ }
+#endif
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2ForUnity.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2ForUnity.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2ForUnity.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ForUnity.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2ListenerExample.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2ListenerExample.cs
similarity index 96%
rename from src/Ros2ForUnity/Scripts/ROS2ListenerExample.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ListenerExample.cs
index d145359..7433221 100644
--- a/src/Ros2ForUnity/Scripts/ROS2ListenerExample.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2ListenerExample.cs
@@ -1,46 +1,46 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using UnityEngine;
-
-namespace ROS2
-{
-
-///
-/// An example class provided for testing of basic ROS2 communication
-///
-public class ROS2ListenerExample : MonoBehaviour
-{
- private ROS2UnityComponent ros2Unity;
- private ROS2Node ros2Node;
- private ISubscription chatter_sub;
-
- void Start()
- {
- ros2Unity = GetComponent();
- }
-
- void Update()
- {
- if (ros2Node == null && ros2Unity.Ok())
- {
- ros2Node = ros2Unity.CreateNode("ROS2UnityListenerNode");
- chatter_sub = ros2Node.CreateSubscription(
- "chatter", msg => Debug.Log("Unity listener heard: [" + msg.Data + "]"));
- }
- }
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using UnityEngine;
+
+namespace ROS2
+{
+
+///
+/// An example class provided for testing of basic ROS2 communication
+///
+public class ROS2ListenerExample : MonoBehaviour
+{
+ private ROS2UnityComponent ros2Unity;
+ private ROS2Node ros2Node;
+ private ISubscription chatter_sub;
+
+ void Start()
+ {
+ ros2Unity = GetComponent();
+ }
+
+ void Update()
+ {
+ if (ros2Node == null && ros2Unity.Ok())
+ {
+ ros2Node = ros2Unity.CreateNode("ROS2UnityListenerNode");
+ chatter_sub = ros2Node.CreateSubscription(
+ "chatter", msg => Debug.Log("Unity listener heard: [" + msg.Data + "]"));
+ }
+ }
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2ListenerExample.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2ListenerExample.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2ListenerExample.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ListenerExample.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2Node.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2Node.cs
similarity index 97%
rename from src/Ros2ForUnity/Scripts/ROS2Node.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2Node.cs
index ad74fca..e007a0e 100644
--- a/src/Ros2ForUnity/Scripts/ROS2Node.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2Node.cs
@@ -1,151 +1,151 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEditor;
-
-namespace ROS2
-{
-
-///
-/// A class representing a ros2 node. Multiple nodes can be used. Node can be removed by GC when not used anymore,
-/// but will also be removed properly with Ros2cs Shutdown, which ROS2 for Unity performs on application quit
-/// The node should be constructed through ROS2UnityComponent class, which also handles spinning
-///
-public class ROS2Node
-{
- internal INode node;
- public ROS2Clock clock;
- public string name;
-
- // Use ROS2UnityComponent to create a node
- internal ROS2Node(string unityROS2NodeName = "unity_ros2_node")
- {
- name = unityROS2NodeName;
- node = Ros2cs.CreateNode(name);
- clock = new ROS2Clock();
- }
-
- ~ROS2Node()
- {
- Ros2cs.RemoveNode(node);
- }
-
- private static void ThrowIfUninitialized(string callContext)
- {
- if (!Ros2cs.Ok())
- {
- throw new InvalidOperationException("Ros2 For Unity is not initialized, can't " + callContext);
- }
- }
-
- ///
- /// Create a publisher with QoS suitable for sensor data
- ///
- /// The publisher
- /// topic that will be used for publishing
- public Publisher CreateSensorPublisher(string topicName) where T : Message, new()
- {
- QualityOfServiceProfile sensorProfile = new QualityOfServiceProfile(QosPresetProfile.SENSOR_DATA);
- return CreatePublisher(topicName, sensorProfile);
- }
-
- ///
- /// Create a publisher with indicated QoS.
- ///
- /// The publisher
- /// topic that will be used for publishing
- /// QoS for publishing. If no QoS is selected, it will default to reliable, keep 10 last
- public Publisher CreatePublisher(string topicName, QualityOfServiceProfile qos = null) where T : Message, new()
- {
- ThrowIfUninitialized("create publisher");
- return node.CreatePublisher(topicName, qos);
- }
-
- ///
- /// Create a subscription
- ///
- /// The subscription
- /// topic to subscribe to
- /// QoS for subscription. If no QoS is selected, it will default to reliable, keep 10 last
- public Subscription CreateSubscription(string topicName, Action callback,
- QualityOfServiceProfile qos = null) where T : Message, new()
- {
- if (qos == null)
- {
- qos = new QualityOfServiceProfile(QosPresetProfile.DEFAULT);
- }
- ThrowIfUninitialized("create subscription");
- return node.CreateSubscription(topicName, callback, qos);
- }
-
-
- ///
- /// Remove existing subscription (returned earlier with CreateSubscription)
- ///
- /// The whether subscription was found (e. g. false if removed earlier elsewhere)
- /// subscrition to remove, returned from CreateSubscription
- public bool RemoveSubscription(ISubscriptionBase subscription)
- {
- ThrowIfUninitialized("remove subscription");
- return node.RemoveSubscription(subscription);
- }
-
- ///
- /// Remove existing publisher
- ///
- /// The whether publisher was found (e. g. false if removed earlier elsewhere)
- /// publisher to remove, returned from CreatePublisher or CreateSensorPublisher
- public bool RemovePublisher(IPublisherBase publisher)
- {
- ThrowIfUninitialized("remove publisher");
- return node.RemovePublisher(publisher);
- }
-
- ///
- public Service CreateService(string topic, Func callback, QualityOfServiceProfile qos = null)
- where I : Message, new()
- where O : Message, new()
- {
- ThrowIfUninitialized("create service");
- return node.CreateService(topic, callback, qos);
- }
-
- ///
- public bool RemoveService(IServiceBase service)
- {
- ThrowIfUninitialized("remove service");
- return node.RemoveService(service);
- }
-
- ///
- public Client CreateClient(string topic, QualityOfServiceProfile qos = null)
- where I : Message, new()
- where O : Message, new()
- {
- ThrowIfUninitialized(callContext: "create client");
- return node.CreateClient(topic, qos);
- }
-
- ///
- public bool RemoveClient(IClientBase client)
- {
- ThrowIfUninitialized(callContext: "remove client");
- return node.RemoveClient(client);
- }
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+namespace ROS2
+{
+
+///
+/// A class representing a ros2 node. Multiple nodes can be used. Node can be removed by GC when not used anymore,
+/// but will also be removed properly with Ros2cs Shutdown, which ROS2 for Unity performs on application quit
+/// The node should be constructed through ROS2UnityComponent class, which also handles spinning
+///
+public class ROS2Node
+{
+ internal INode node;
+ public ROS2Clock clock;
+ public string name;
+
+ // Use ROS2UnityComponent to create a node
+ internal ROS2Node(string unityROS2NodeName = "unity_ros2_node")
+ {
+ name = unityROS2NodeName;
+ node = Ros2cs.CreateNode(name);
+ clock = new ROS2Clock();
+ }
+
+ ~ROS2Node()
+ {
+ Ros2cs.RemoveNode(node);
+ }
+
+ private static void ThrowIfUninitialized(string callContext)
+ {
+ if (!Ros2cs.Ok())
+ {
+ throw new InvalidOperationException("Ros2 For Unity is not initialized, can't " + callContext);
+ }
+ }
+
+ ///
+ /// Create a publisher with QoS suitable for sensor data
+ ///
+ /// The publisher
+ /// topic that will be used for publishing
+ public Publisher CreateSensorPublisher(string topicName) where T : Message, new()
+ {
+ QualityOfServiceProfile sensorProfile = new QualityOfServiceProfile(QosPresetProfile.SENSOR_DATA);
+ return CreatePublisher(topicName, sensorProfile);
+ }
+
+ ///
+ /// Create a publisher with indicated QoS.
+ ///
+ /// The publisher
+ /// topic that will be used for publishing
+ /// QoS for publishing. If no QoS is selected, it will default to reliable, keep 10 last
+ public Publisher CreatePublisher(string topicName, QualityOfServiceProfile qos = null) where T : Message, new()
+ {
+ ThrowIfUninitialized("create publisher");
+ return node.CreatePublisher(topicName, qos);
+ }
+
+ ///
+ /// Create a subscription
+ ///
+ /// The subscription
+ /// topic to subscribe to
+ /// QoS for subscription. If no QoS is selected, it will default to reliable, keep 10 last
+ public Subscription CreateSubscription(string topicName, Action callback,
+ QualityOfServiceProfile qos = null) where T : Message, new()
+ {
+ if (qos == null)
+ {
+ qos = new QualityOfServiceProfile(QosPresetProfile.DEFAULT);
+ }
+ ThrowIfUninitialized("create subscription");
+ return node.CreateSubscription(topicName, callback, qos);
+ }
+
+
+ ///
+ /// Remove existing subscription (returned earlier with CreateSubscription)
+ ///
+ /// The whether subscription was found (e. g. false if removed earlier elsewhere)
+ /// subscrition to remove, returned from CreateSubscription
+ public bool RemoveSubscription(ISubscriptionBase subscription)
+ {
+ ThrowIfUninitialized("remove subscription");
+ return node.RemoveSubscription(subscription);
+ }
+
+ ///
+ /// Remove existing publisher
+ ///
+ /// The whether publisher was found (e. g. false if removed earlier elsewhere)
+ /// publisher to remove, returned from CreatePublisher or CreateSensorPublisher
+ public bool RemovePublisher(IPublisherBase publisher)
+ {
+ ThrowIfUninitialized("remove publisher");
+ return node.RemovePublisher(publisher);
+ }
+
+ ///
+ public Service CreateService(string topic, Func callback, QualityOfServiceProfile qos = null)
+ where I : Message, new()
+ where O : Message, new()
+ {
+ ThrowIfUninitialized("create service");
+ return node.CreateService(topic, callback, qos);
+ }
+
+ ///
+ public bool RemoveService(IServiceBase service)
+ {
+ ThrowIfUninitialized("remove service");
+ return node.RemoveService(service);
+ }
+
+ ///
+ public Client CreateClient(string topic, QualityOfServiceProfile qos = null)
+ where I : Message, new()
+ where O : Message, new()
+ {
+ ThrowIfUninitialized(callContext: "create client");
+ return node.CreateClient(topic, qos);
+ }
+
+ ///
+ public bool RemoveClient(IClientBase client)
+ {
+ ThrowIfUninitialized(callContext: "remove client");
+ return node.RemoveClient(client);
+ }
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2Node.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2Node.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2Node.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2Node.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2PerformanceTest.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2PerformanceTest.cs
similarity index 96%
rename from src/Ros2ForUnity/Scripts/ROS2PerformanceTest.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2PerformanceTest.cs
index 3b70f3b..84b7e74 100644
--- a/src/Ros2ForUnity/Scripts/ROS2PerformanceTest.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2PerformanceTest.cs
@@ -1,137 +1,137 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using UnityEngine;
-using System.Threading;
-
-namespace ROS2
-{
-
-///
-/// An example class provided for performance testing of ROS2 communication
-///
-public class ROS2PerformanceTest : MonoBehaviour
-{
- public int messageSize = 10000;
- public int rate = 10;
- private int interval_ms = 100;
- private ROS2UnityComponent ros2Unity;
- private ROS2Node ros2Node;
- private IPublisher perf_pub;
- sensor_msgs.msg.PointCloud2 msg;
- private bool initialized = false;
-
- void Start()
- {
- ros2Unity = GetComponent();
- PrepMessage();
- }
-
- void OnValidate()
- {
- if (rate < 1)
- {
- interval_ms = 0;
- }
- else
- {
- interval_ms = 1000 / rate;
- }
- PrepMessage();
- }
-
- private void Publish()
- {
- while(true)
- {
- if (ros2Unity.Ok())
- {
- if (ros2Node == null)
- {
- ros2Node = ros2Unity.CreateNode("ros2_unity_performance_test_node");
- perf_pub = ros2Node.CreateSensorPublisher("perf_chatter");
- }
-
- var msgWithHeader = msg as MessageWithHeader;
- ros2Node.clock.UpdateROSTimestamp(ref msgWithHeader);
- perf_pub.Publish(msg);
- if (interval_ms > 0)
- {
- Thread.Sleep(interval_ms);
- }
- }
- }
- }
-
- void FixedUpdate()
- {
- if (!initialized)
- {
- Thread publishThread = new Thread(() => Publish());
- publishThread.Start();
- initialized = true;
- }
- }
-
- private void AssignField(ref sensor_msgs.msg.PointField pf, string n, uint off, byte dt, uint count)
- {
- pf.Name = n;
- pf.Offset = off;
- pf.Datatype = dt;
- pf.Count = count;
- }
-
- private void PrepMessage()
- {
- uint count = (uint)messageSize; //point per message
- uint fieldsSize = 16;
- uint rowSize = count * fieldsSize;
- msg = new sensor_msgs.msg.PointCloud2()
- {
- Height = 1,
- Width = count,
- Is_bigendian = false,
- Is_dense = true,
- Point_step = fieldsSize,
- Row_step = rowSize,
- Data = new byte[rowSize * 1]
- };
- uint pointFieldCount = 4;
- msg.Fields = new sensor_msgs.msg.PointField[pointFieldCount];
- for (int i = 0; i < pointFieldCount; ++i)
- {
- msg.Fields[i] = new sensor_msgs.msg.PointField();
- }
-
- AssignField(ref msg.Fields[0], "x", 0, 7, 1);
- AssignField(ref msg.Fields[1], "y", 4, 7, 1);
- AssignField(ref msg.Fields[2], "z", 8, 7, 1);
- AssignField(ref msg.Fields[3], "intensity", 12, 7, 1);
- float[] pointsArray = new float[count * msg.Fields.Length];
-
- var floatIndex = 0;
- for (int i = 0; i < count; ++i)
- {
- float intensity = 100;
- pointsArray[floatIndex++] = 1;
- pointsArray[floatIndex++] = 2;
- pointsArray[floatIndex++] = 3;
- pointsArray[floatIndex++] = intensity;
- }
- System.Buffer.BlockCopy(pointsArray, 0, msg.Data, 0, msg.Data.Length);
- msg.SetHeaderFrame("pc");
- }
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using UnityEngine;
+using System.Threading;
+
+namespace ROS2
+{
+
+///
+/// An example class provided for performance testing of ROS2 communication
+///
+public class ROS2PerformanceTest : MonoBehaviour
+{
+ public int messageSize = 10000;
+ public int rate = 10;
+ private int interval_ms = 100;
+ private ROS2UnityComponent ros2Unity;
+ private ROS2Node ros2Node;
+ private IPublisher perf_pub;
+ sensor_msgs.msg.PointCloud2 msg;
+ private bool initialized = false;
+
+ void Start()
+ {
+ ros2Unity = GetComponent();
+ PrepMessage();
+ }
+
+ void OnValidate()
+ {
+ if (rate < 1)
+ {
+ interval_ms = 0;
+ }
+ else
+ {
+ interval_ms = 1000 / rate;
+ }
+ PrepMessage();
+ }
+
+ private void Publish()
+ {
+ while(true)
+ {
+ if (ros2Unity.Ok())
+ {
+ if (ros2Node == null)
+ {
+ ros2Node = ros2Unity.CreateNode("ros2_unity_performance_test_node");
+ perf_pub = ros2Node.CreateSensorPublisher("perf_chatter");
+ }
+
+ var msgWithHeader = msg as MessageWithHeader;
+ ros2Node.clock.UpdateROSTimestamp(ref msgWithHeader);
+ perf_pub.Publish(msg);
+ if (interval_ms > 0)
+ {
+ Thread.Sleep(interval_ms);
+ }
+ }
+ }
+ }
+
+ void FixedUpdate()
+ {
+ if (!initialized)
+ {
+ Thread publishThread = new Thread(() => Publish());
+ publishThread.Start();
+ initialized = true;
+ }
+ }
+
+ private void AssignField(ref sensor_msgs.msg.PointField pf, string n, uint off, byte dt, uint count)
+ {
+ pf.Name = n;
+ pf.Offset = off;
+ pf.Datatype = dt;
+ pf.Count = count;
+ }
+
+ private void PrepMessage()
+ {
+ uint count = (uint)messageSize; //point per message
+ uint fieldsSize = 16;
+ uint rowSize = count * fieldsSize;
+ msg = new sensor_msgs.msg.PointCloud2()
+ {
+ Height = 1,
+ Width = count,
+ Is_bigendian = false,
+ Is_dense = true,
+ Point_step = fieldsSize,
+ Row_step = rowSize,
+ Data = new byte[rowSize * 1]
+ };
+ uint pointFieldCount = 4;
+ msg.Fields = new sensor_msgs.msg.PointField[pointFieldCount];
+ for (int i = 0; i < pointFieldCount; ++i)
+ {
+ msg.Fields[i] = new sensor_msgs.msg.PointField();
+ }
+
+ AssignField(ref msg.Fields[0], "x", 0, 7, 1);
+ AssignField(ref msg.Fields[1], "y", 4, 7, 1);
+ AssignField(ref msg.Fields[2], "z", 8, 7, 1);
+ AssignField(ref msg.Fields[3], "intensity", 12, 7, 1);
+ float[] pointsArray = new float[count * msg.Fields.Length];
+
+ var floatIndex = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ float intensity = 100;
+ pointsArray[floatIndex++] = 1;
+ pointsArray[floatIndex++] = 2;
+ pointsArray[floatIndex++] = 3;
+ pointsArray[floatIndex++] = intensity;
+ }
+ System.Buffer.BlockCopy(pointsArray, 0, msg.Data, 0, msg.Data.Length);
+ msg.SetHeaderFrame("pc");
+ }
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2PerformanceTest.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2PerformanceTest.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2PerformanceTest.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2PerformanceTest.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2ServiceExample.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2ServiceExample.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2ServiceExample.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2ServiceExample.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/ROS2ServiceExample.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2ServiceExample.cs.meta
new file mode 100644
index 0000000..8d21546
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2ServiceExample.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 77ca4f3ef22cdb943ba7dc008cebddbd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/ROS2TalkerExample.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2TalkerExample.cs
similarity index 96%
rename from src/Ros2ForUnity/Scripts/ROS2TalkerExample.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2TalkerExample.cs
index 705ea0d..c56d1a2 100644
--- a/src/Ros2ForUnity/Scripts/ROS2TalkerExample.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2TalkerExample.cs
@@ -1,54 +1,54 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using UnityEngine;
-
-namespace ROS2
-{
-
-///
-/// An example class provided for testing of basic ROS2 communication
-///
-public class ROS2TalkerExample : MonoBehaviour
-{
- // Start is called before the first frame update
- private ROS2UnityComponent ros2Unity;
- private ROS2Node ros2Node;
- private IPublisher chatter_pub;
- private int i;
-
- void Start()
- {
- ros2Unity = GetComponent();
- }
-
- void Update()
- {
- if (ros2Unity.Ok())
- {
- if (ros2Node == null)
- {
- ros2Node = ros2Unity.CreateNode("ROS2UnityTalkerNode");
- chatter_pub = ros2Node.CreatePublisher("chatter");
- }
-
- i++;
- std_msgs.msg.String msg = new std_msgs.msg.String();
- msg.Data = "Unity ROS2 sending: hello " + i;
- chatter_pub.Publish(msg);
- }
- }
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using UnityEngine;
+
+namespace ROS2
+{
+
+///
+/// An example class provided for testing of basic ROS2 communication
+///
+public class ROS2TalkerExample : MonoBehaviour
+{
+ // Start is called before the first frame update
+ private ROS2UnityComponent ros2Unity;
+ private ROS2Node ros2Node;
+ private IPublisher chatter_pub;
+ private int i;
+
+ void Start()
+ {
+ ros2Unity = GetComponent();
+ }
+
+ void Update()
+ {
+ if (ros2Unity.Ok())
+ {
+ if (ros2Node == null)
+ {
+ ros2Node = ros2Unity.CreateNode("ROS2UnityTalkerNode");
+ chatter_pub = ros2Node.CreatePublisher("chatter");
+ }
+
+ i++;
+ std_msgs.msg.String msg = new std_msgs.msg.String();
+ msg.Data = "Unity ROS2 sending: hello " + i;
+ chatter_pub.Publish(msg);
+ }
+ }
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2TalkerExample.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2TalkerExample.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2TalkerExample.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2TalkerExample.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2UnityComponent.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2UnityComponent.cs
similarity index 96%
rename from src/Ros2ForUnity/Scripts/ROS2UnityComponent.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2UnityComponent.cs
index 24018c8..7c916e2 100644
--- a/src/Ros2ForUnity/Scripts/ROS2UnityComponent.cs
+++ b/src/Ros2ForUnity/Runtime/Scripts/ROS2UnityComponent.cs
@@ -1,164 +1,164 @@
-// Copyright 2019-2021 Robotec.ai.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using UnityEngine;
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using ROS2;
-
-namespace ROS2
-{
-
-///
-/// The principal MonoBehaviour class for handling ros2 nodes and executables.
-/// Use this to create ros2 node, check ros2 status.
-/// Spins and executes actions (e. g. clock, sensor publish triggers) in a dedicated thread
-/// TODO: this is meant to be used as a one-of (a singleton). Enforce. However, things should work
-/// anyway with more than one since the underlying library can handle multiple init and shutdown calls,
-/// and does node name uniqueness check independently.
-///
-public class ROS2UnityComponent : MonoBehaviour
-{
- private ROS2ForUnity ros2forUnity;
- private List nodes;
- private List ros2csNodes; // For performance in spinning
- private List executableActions;
- private bool initialized = false;
- private bool quitting = false;
- private int interval = 2; // Spinning / executor interval in ms
- private object mutex = new object();
- private double spinTimeout = 0.0001;
-
- public bool Ok()
- {
- lock (mutex)
- {
- if (ros2forUnity == null)
- LazyConstruct();
- return (nodes != null && ros2forUnity.Ok());
- }
- }
-
- private void LazyConstruct()
- {
- lock (mutex)
- {
- if (ros2forUnity != null)
- return;
-
- ros2forUnity = new ROS2ForUnity();
- nodes = new List();
- ros2csNodes = new List();
- executableActions = new List();
- }
- }
-
- void Start()
- {
- LazyConstruct();
- }
-
- public ROS2Node CreateNode(string name)
- {
- LazyConstruct();
-
- lock (mutex)
- {
- foreach (ROS2Node n in nodes)
- { // Assumed to be a rare operation on rather small (<1k) list
- if (n.name == name)
- {
- throw new InvalidOperationException("Cannot create node " + name + ". A node with this name already exists!");
- }
- }
- ROS2Node node = new ROS2Node(name);
- nodes.Add(node);
- ros2csNodes.Add(node.node);
- return node;
- }
- }
-
- public void RemoveNode(ROS2Node node)
- {
- lock (mutex)
- {
- ros2csNodes.Remove(node.node);
- nodes.Remove(node); //Node will be later deleted if unused, by GC
- }
- }
-
- ///
- /// Works as a simple executor registration analogue. These functions will be called with each Tick()
- /// Actions need to take care of correct call resolution by checking in their body (TODO)
- /// Make sure actions are lightweight (TODO - separate out threads for spinning and executables?)
- ///
- public void RegisterExecutable(Action executable)
- {
- LazyConstruct();
-
- lock (mutex)
- {
- executableActions.Add(executable);
- }
- }
-
- public void UnregisterExecutable(Action executable)
- {
- lock (mutex)
- {
- executableActions.Remove(executable);
- }
- }
-
- ///
- /// "Executor" thread will tick all clocks and spin the node
- ///
- private void Tick()
- {
- while (!quitting)
- {
- if (Ok())
- {
- lock (mutex)
- {
- foreach (Action action in executableActions)
- {
- action();
- }
- Ros2cs.SpinOnce(ros2csNodes, spinTimeout);
- }
- }
- Thread.Sleep(interval);
- }
- }
-
- void FixedUpdate()
- {
- if (!initialized)
- {
- Thread publishThread = new Thread(() => Tick());
- publishThread.Start();
- initialized = true;
- }
- }
-
- void OnApplicationQuit()
- {
- quitting = true;
- ros2forUnity.DestroyROS2ForUnity();
- }
-}
-
-} // namespace ROS2
+// Copyright 2019-2021 Robotec.ai.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using UnityEngine;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using ROS2;
+
+namespace ROS2
+{
+
+///
+/// The principal MonoBehaviour class for handling ros2 nodes and executables.
+/// Use this to create ros2 node, check ros2 status.
+/// Spins and executes actions (e. g. clock, sensor publish triggers) in a dedicated thread
+/// TODO: this is meant to be used as a one-of (a singleton). Enforce. However, things should work
+/// anyway with more than one since the underlying library can handle multiple init and shutdown calls,
+/// and does node name uniqueness check independently.
+///
+public class ROS2UnityComponent : MonoBehaviour
+{
+ private ROS2ForUnity ros2forUnity;
+ private List nodes;
+ private List ros2csNodes; // For performance in spinning
+ private List executableActions;
+ private bool initialized = false;
+ private bool quitting = false;
+ private int interval = 2; // Spinning / executor interval in ms
+ private object mutex = new object();
+ private double spinTimeout = 0.0001;
+
+ public bool Ok()
+ {
+ lock (mutex)
+ {
+ if (ros2forUnity == null)
+ LazyConstruct();
+ return (nodes != null && ros2forUnity.Ok());
+ }
+ }
+
+ private void LazyConstruct()
+ {
+ lock (mutex)
+ {
+ if (ros2forUnity != null)
+ return;
+
+ ros2forUnity = new ROS2ForUnity();
+ nodes = new List();
+ ros2csNodes = new List();
+ executableActions = new List();
+ }
+ }
+
+ void Start()
+ {
+ LazyConstruct();
+ }
+
+ public ROS2Node CreateNode(string name)
+ {
+ LazyConstruct();
+
+ lock (mutex)
+ {
+ foreach (ROS2Node n in nodes)
+ { // Assumed to be a rare operation on rather small (<1k) list
+ if (n.name == name)
+ {
+ throw new InvalidOperationException("Cannot create node " + name + ". A node with this name already exists!");
+ }
+ }
+ ROS2Node node = new ROS2Node(name);
+ nodes.Add(node);
+ ros2csNodes.Add(node.node);
+ return node;
+ }
+ }
+
+ public void RemoveNode(ROS2Node node)
+ {
+ lock (mutex)
+ {
+ ros2csNodes.Remove(node.node);
+ nodes.Remove(node); //Node will be later deleted if unused, by GC
+ }
+ }
+
+ ///
+ /// Works as a simple executor registration analogue. These functions will be called with each Tick()
+ /// Actions need to take care of correct call resolution by checking in their body (TODO)
+ /// Make sure actions are lightweight (TODO - separate out threads for spinning and executables?)
+ ///
+ public void RegisterExecutable(Action executable)
+ {
+ LazyConstruct();
+
+ lock (mutex)
+ {
+ executableActions.Add(executable);
+ }
+ }
+
+ public void UnregisterExecutable(Action executable)
+ {
+ lock (mutex)
+ {
+ executableActions.Remove(executable);
+ }
+ }
+
+ ///
+ /// "Executor" thread will tick all clocks and spin the node
+ ///
+ private void Tick()
+ {
+ while (!quitting)
+ {
+ if (Ok())
+ {
+ lock (mutex)
+ {
+ foreach (Action action in executableActions)
+ {
+ action();
+ }
+ Ros2cs.SpinOnce(ros2csNodes, spinTimeout);
+ }
+ }
+ Thread.Sleep(interval);
+ }
+ }
+
+ void FixedUpdate()
+ {
+ if (!initialized)
+ {
+ Thread publishThread = new Thread(() => Tick());
+ publishThread.Start();
+ initialized = true;
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ quitting = true;
+ ros2forUnity.DestroyROS2ForUnity();
+ }
+}
+
+} // namespace ROS2
diff --git a/src/Ros2ForUnity/Scripts/ROS2UnityComponent.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2UnityComponent.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2UnityComponent.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2UnityComponent.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/ROS2UnityCore.cs b/src/Ros2ForUnity/Runtime/Scripts/ROS2UnityCore.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2UnityCore.cs
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2UnityCore.cs
diff --git a/src/Ros2ForUnity/Scripts/ROS2UnityCore.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/ROS2UnityCore.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/ROS2UnityCore.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/ROS2UnityCore.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/Sensor.cs b/src/Ros2ForUnity/Runtime/Scripts/Sensor.cs
old mode 100755
new mode 100644
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Sensor.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Sensor.cs
diff --git a/src/Ros2ForUnity/Scripts/Sensor.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Sensor.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Sensor.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/Sensor.cs.meta
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time.meta b/src/Ros2ForUnity/Runtime/Scripts/Time.meta
new file mode 100644
index 0000000..20aa921
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7733f1d2b41af9b4085ad9a8315c3ead
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/DotnetTimeSource.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/DotnetTimeSource.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/DotnetTimeSource.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time/DotnetTimeSource.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/DotnetTimeSource.cs.meta
new file mode 100644
index 0000000..e400099
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time/DotnetTimeSource.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dbe7b625291ce71418e89f80c5846349
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Time/ITimeSource.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/ITimeSource.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/ITimeSource.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/ITimeSource.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time/ITimeSource.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/ITimeSource.cs.meta
new file mode 100644
index 0000000..09413e0
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time/ITimeSource.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8a6b77a55c98705439d95de6bebe5fa7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Time/ROS2Clock.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2Clock.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/ROS2Clock.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/ROS2Clock.cs
diff --git a/src/Ros2ForUnity/Scripts/Time/ROS2Clock.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2Clock.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/ROS2Clock.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/Time/ROS2Clock.cs.meta
diff --git a/src/Ros2ForUnity/Scripts/Time/ROS2TimeSource.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2TimeSource.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/ROS2TimeSource.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/ROS2TimeSource.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2TimeSource.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2TimeSource.cs.meta
new file mode 100644
index 0000000..d259279
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time/ROS2TimeSource.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2bbfe7ca89c391244af9c394486efcb0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Time/TimeUtils.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/TimeUtils.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/TimeUtils.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/TimeUtils.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time/TimeUtils.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/TimeUtils.cs.meta
new file mode 100644
index 0000000..32a55a9
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time/TimeUtils.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ae7c5c02efdefa94daaf1550b254a8e0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs b/src/Ros2ForUnity/Runtime/Scripts/Time/UnityTimeSource.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Time/UnityTimeSource.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Time/UnityTimeSource.cs
diff --git a/src/Ros2ForUnity/Runtime/Scripts/Time/UnityTimeSource.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Time/UnityTimeSource.cs.meta
new file mode 100644
index 0000000..eb532bb
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/Scripts/Time/UnityTimeSource.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4d78097250d392444a5902b58762d38d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Scripts/Transformations.cs b/src/Ros2ForUnity/Runtime/Scripts/Transformations.cs
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Transformations.cs
rename to src/Ros2ForUnity/Runtime/Scripts/Transformations.cs
diff --git a/src/Ros2ForUnity/Scripts/Transformations.cs.meta b/src/Ros2ForUnity/Runtime/Scripts/Transformations.cs.meta
similarity index 100%
rename from src/Ros2ForUnity/Scripts/Transformations.cs.meta
rename to src/Ros2ForUnity/Runtime/Scripts/Transformations.cs.meta
diff --git a/src/Ros2ForUnity/Runtime/metadata_ros2_for_unity.xml.meta b/src/Ros2ForUnity/Runtime/metadata_ros2_for_unity.xml.meta
new file mode 100644
index 0000000..5a05eb3
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/metadata_ros2_for_unity.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 239875d8263fd93429bd313e9767cb11
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Runtime/metadata_ros2cs.xml.meta b/src/Ros2ForUnity/Runtime/metadata_ros2cs.xml.meta
new file mode 100644
index 0000000..b06fb61
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/metadata_ros2cs.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 459adb1c8300ac047b95fa3ea165bf89
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef b/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef
new file mode 100644
index 0000000..feb534d
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef
@@ -0,0 +1,14 @@
+{
+ "name": "RobotecAI.ROS2-for-Unity",
+ "rootNamespace": "",
+ "references": [],
+ "includePlatforms": [],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": false,
+ "precompiledReferences": [],
+ "autoReferenced": true,
+ "defineConstraints": [],
+ "versionDefines": [],
+ "noEngineReferences": false
+}
diff --git a/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef.meta b/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef.meta
new file mode 100644
index 0000000..36ac666
--- /dev/null
+++ b/src/Ros2ForUnity/Runtime/robotecai.ros2-for-unity.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ac79f61176286e84f93be5f4e048d950
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/Ros2ForUnity/package.json b/src/Ros2ForUnity/package.json
new file mode 100644
index 0000000..21cb40e
--- /dev/null
+++ b/src/Ros2ForUnity/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "com.robotecai.ros2-for-unity",
+ "version": "1.3.0",
+ "displayName": "ROS2 For Unity",
+ "description": "Integration of ROS2 with Unity",
+ "unity": "2022.3",
+ "unityRelease": "5f1",
+ "documentationUrl": "https://github.com/RobotecAI/ros2-for-unity/",
+ "licensesUrl": "https://github.com/RobotecAI/ros2-for-unity/blob/develop/LICENSE.AL2",
+ "author": {
+ "name": "RobotecAI",
+ "email": "office@robotec.ai",
+ "url": "http://www.robotec.ai/"
+ }
+}
diff --git a/src/Ros2ForUnity/package.json.meta b/src/Ros2ForUnity/package.json.meta
new file mode 100644
index 0000000..118a183
--- /dev/null
+++ b/src/Ros2ForUnity/package.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 86a52626cb10818438fb3dc6c2a23337
+PackageManifestImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/scripts/metadata_generator.py b/src/scripts/metadata_generator.py
index 25f6c40..a41180e 100644
--- a/src/scripts/metadata_generator.py
+++ b/src/scripts/metadata_generator.py
@@ -39,7 +39,7 @@ def get_ros2_for_unity_root_path() -> pathlib.Path:
return pathlib.Path(__file__).parents[2]
def get_ros2_for_unity_path() -> pathlib.Path:
- return pathlib.Path(__file__).parents[1].joinpath("Ros2ForUnity")
+ return pathlib.Path(__file__).parents[1].joinpath("Ros2ForUnity").joinpath("Runtime")
def get_ros2cs_path() -> pathlib.Path:
return pathlib.Path(__file__).parents[1].joinpath("ros2cs")