From 44da6410d26c89cb72de56219fb8fe553de4e300 Mon Sep 17 00:00:00 2001 From: xyf <351095656@qq.com> Date: Wed, 23 Apr 2025 10:21:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(csharp):=20=E6=B7=BB=E5=8A=A0=20csharp=20?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- recipes/ros2_csharp/activate.bat | 6 + recipes/ros2_csharp/deactivate.bat | 6 + recipes/ros2_csharp/meta.yaml | 42 ++++ recipes/ros2_csharp/ros_driver | 0 ros2_csharp/README.md | 38 +++ ros2_csharp/ros2_humble.repos | 33 +++ ros2_csharp/src/ros_driver/CMakeLists.txt | 65 ++++++ .../src/ros_driver/DeviceActionServer.cs | 133 +++++++++++ ros2_csharp/src/ros_driver/DeviceNode.cs | 173 ++++++++++++++ ros2_csharp/src/ros_driver/MockGripper.cs | 73 ++++++ ros2_csharp/src/ros_driver/Program.cs | 65 ++++++ .../src/ros_driver/PropertyPublisher.cs | 217 ++++++++++++++++++ .../ros_driver/deps/YamlDotNet/YamlDotNet.dll | Bin 0 -> 292352 bytes ros2_csharp/src/ros_driver/package.xml | 38 +++ .../src/ros_driver/utils/MessageConverter.cs | 154 +++++++++++++ ros2_csharp/src/ros_driver/utils/Yaml.cs | 143 ++++++++++++ 16 files changed, 1186 insertions(+) create mode 100644 recipes/ros2_csharp/activate.bat create mode 100644 recipes/ros2_csharp/deactivate.bat create mode 100644 recipes/ros2_csharp/meta.yaml create mode 100644 recipes/ros2_csharp/ros_driver create mode 100644 ros2_csharp/README.md create mode 100644 ros2_csharp/ros2_humble.repos create mode 100644 ros2_csharp/src/ros_driver/CMakeLists.txt create mode 100644 ros2_csharp/src/ros_driver/DeviceActionServer.cs create mode 100644 ros2_csharp/src/ros_driver/DeviceNode.cs create mode 100644 ros2_csharp/src/ros_driver/MockGripper.cs create mode 100644 ros2_csharp/src/ros_driver/Program.cs create mode 100644 ros2_csharp/src/ros_driver/PropertyPublisher.cs create mode 100644 ros2_csharp/src/ros_driver/deps/YamlDotNet/YamlDotNet.dll create mode 100644 ros2_csharp/src/ros_driver/package.xml create mode 100644 ros2_csharp/src/ros_driver/utils/MessageConverter.cs create mode 100644 ros2_csharp/src/ros_driver/utils/Yaml.cs diff --git a/recipes/ros2_csharp/activate.bat b/recipes/ros2_csharp/activate.bat new file mode 100644 index 00000000..5cd8c17d --- /dev/null +++ b/recipes/ros2_csharp/activate.bat @@ -0,0 +1,6 @@ +@echo off +set AMENT_PREFIX_PATH_BACKUP=%AMENT_PREFIX_PATH% +set AMENT_PREFIX_PATH=%CONDA_PREFIX%\Library +set PATH=%CONDA_PREFIX%\Library\bin;%PATH% +set CMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library;%CMAKE_PREFIX_PATH% +set PYTHONPATH=%CONDA_PREFIX%\Lib\site-packages;%PYTHONPATH% \ No newline at end of file diff --git a/recipes/ros2_csharp/deactivate.bat b/recipes/ros2_csharp/deactivate.bat new file mode 100644 index 00000000..b0b09a13 --- /dev/null +++ b/recipes/ros2_csharp/deactivate.bat @@ -0,0 +1,6 @@ +@echo off +set AMENT_PREFIX_PATH=%AMENT_PREFIX_PATH_BACKUP% +set AMENT_PREFIX_PATH_BACKUP= +set PATH=%PATH:%CONDA_PREFIX%\Library\bin;=% +set CMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH:%CONDA_PREFIX%\Library;=% +set PYTHONPATH=%PYTHONPATH:%CONDA_PREFIX%\Lib\site-packages;=% \ No newline at end of file diff --git a/recipes/ros2_csharp/meta.yaml b/recipes/ros2_csharp/meta.yaml new file mode 100644 index 00000000..d47566bc --- /dev/null +++ b/recipes/ros2_csharp/meta.yaml @@ -0,0 +1,42 @@ +package: + name: ros2_csharp + version: 0.0.1 + +source: + path: {{ 你的安装打包目录 }} + +build: + number: 0 + script: + # 创建基本目录 + - mkdir %PREFIX%\Library\bin 2>nul + - mkdir %PREFIX%\Library\include 2>nul + - mkdir %PREFIX%\Library\lib 2>nul + - mkdir %PREFIX%\Library\share 2>nul + # 复制文件 + - xcopy /E /I /Y %SRC_DIR%\bin %PREFIX%\Library\bin + - xcopy /E /I /Y %SRC_DIR%\include %PREFIX%\Library\include + - xcopy /E /I /Y %SRC_DIR%\lib %PREFIX%\Library\lib + - xcopy /E /I /Y %SRC_DIR%\share %PREFIX%\Library\share + + # 关键:注册ROS 2包 + - mkdir %PREFIX%\Library\share\ament_index\resource_index\packages 2>nul + - copy %RECIPE_DIR%\ros_driver %PREFIX%\Library\share\ament_index\resource_index\packages\ros_driver + + # 设置环境变量 + - mkdir %PREFIX%\etc\conda\activate.d 2>nul + - mkdir %PREFIX%\etc\conda\deactivate.d 2>nul + # activate脚本 + - copy %RECIPE_DIR%\activate.bat %PREFIX%\etc\conda\activate.d\ros_csharp.bat + - copy %RECIPE_DIR%\deactivate.bat %PREFIX%\etc\conda\deactivate.d\ros_csharp.bat + + +requirements: + host: + run: + +about: + home: https://www.ros.org/ + license: BSD-3-Clause + summary: | + Robot Operating System \ No newline at end of file diff --git a/recipes/ros2_csharp/ros_driver b/recipes/ros2_csharp/ros_driver new file mode 100644 index 00000000..e69de29b diff --git a/ros2_csharp/README.md b/ros2_csharp/README.md new file mode 100644 index 00000000..c632bef9 --- /dev/null +++ b/ros2_csharp/README.md @@ -0,0 +1,38 @@ +## ros2 C# 开发指南 + +## 背景 + 该项目是一个示例项目,帮您快速的配置 C# 开发环境。具体硬件设备驱动需要您自行编写。 + + +## C# 开发环境配置 +### 1. 安装 dotnet 环境 +dotnet [下载地址](https://dotnet.microsoft.com/zh-cn/download) +安装完成后执行一下命令,如果安装成功会有如下展示。 +``` + dotnet --version + 8.0.406 +``` + +### 2. ros2-humble 安装 + 请参照官方[安装文档](https://docs.ros.org/en/humble/Installation/Windows-Install-Binary.html) + +### 3. 开发配置 +1. ros2_dotnet 环境配置请参阅[配置文档](https://github.com/ros2-dotnet/ros2_dotnet/blob/main/README.md)。 +2. 参照项目下的 ros_driver 创建您自己的项目。 +3. 编写相应的代码。 +4. 构建流程 + ``` + 打开 windows 搜索 Developer Command Prompt 启动 visual studio + cd {本地ros2-humble} 目录 + call ./local_setup.bat + cd {Uni-Lab-OS 项目目录}/ros_csharp + vcs import ./src < ros2_humble.repos + colcon build --merge-install --packages-up-to {your package name} --event-handlers console_cohesion+ + ``` +5. 拷贝编译完成的包到conda 对应的虚拟环境目录下。 +6. 执行如下命令运行测试 + + ``` + 参照 ros_driver 项目,需要配置 CONFIG_FILE_PATH 环境变量,对应的值是 {Uni-Lab-OS 路径}/unilabos/registry/devices 下的 yaml 文件路径。 + ros2 run {项目包名} {可执行程序名} + ``` \ No newline at end of file diff --git a/ros2_csharp/ros2_humble.repos b/ros2_csharp/ros2_humble.repos new file mode 100644 index 00000000..d2828134 --- /dev/null +++ b/ros2_csharp/ros2_humble.repos @@ -0,0 +1,33 @@ +repositories: + ament_dotnet/ament_cmake_export_assemblies: + type: git + url: https://github.com/ros2-dotnet/ament_cmake_export_assemblies.git + version: main + ros2/common_interfaces: + type: git + url: https://github.com/ros2/common_interfaces.git + version: 4.2.4 + ros2/rcl_interfaces: + type: git + url: https://github.com/ros2/rcl_interfaces.git + version: 1.2.1 + ros2/rosidl_defaults: + type: git + url: https://github.com/ros2/rosidl_defaults.git + version: 1.2.0 + ros2/test_interface_files: + type: git + url: https://github.com/ros2/test_interface_files.git + version: humble + ros2/unique_identifier_msgs: + type: git + url: https://github.com/ros2/unique_identifier_msgs.git + version: 2.2.1 + ros2_dotnet/dotnet_cmake_module: + type: git + url: https://github.com/ros2-dotnet/dotnet_cmake_module.git + version: main + ros2_dotnet/ros2_dotnet: + type: git + url: https://github.com/ros2-dotnet/ros2_dotnet.git + version: main \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/CMakeLists.txt b/ros2_csharp/src/ros_driver/CMakeLists.txt new file mode 100644 index 00000000..ee0cf131 --- /dev/null +++ b/ros2_csharp/src/ros_driver/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.5) + +project(ros_driver C) + +find_package(ament_cmake REQUIRED) +find_package(rcldotnet REQUIRED) + +find_package(rcldotnet_common REQUIRED) + +find_package(builtin_interfaces REQUIRED) +find_package(std_msgs REQUIRED) +find_package(std_srvs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(test_msgs REQUIRED) +find_package(action_msgs REQUIRED) # Add this line +find_package(rcldotnet REQUIRED) +find_package(ilabos_msgs REQUIRED) + + + +find_package(dotnet_cmake_module REQUIRED) + +set(CSHARP_TARGET_FRAMEWORK "netcoreapp6.0") +find_package(DotNETExtra REQUIRED) + + +# 使用相对路径定位 YamlDotNet.dll +set(YAMLDOTNET_DLL "${CMAKE_CURRENT_SOURCE_DIR}/deps/YamlDotNet/YamlDotNet.dll") + +# 检查文件是否存在 +if(NOT EXISTS ${YAMLDOTNET_DLL}) + message(FATAL_ERROR "YamlDotNet.dll not found at: ${YAMLDOTNET_DLL}") +endif() + + +set(_assemblies_dep_dlls + ${rcldotnet_common_ASSEMBLIES_DLL} + ${rcldotnet_ASSEMBLIES_DLL} + ${builtin_interfaces_ASSEMBLIES_DLL} + ${std_msgs_ASSEMBLIES_DLL} + ${std_srvs_ASSEMBLIES_DLL} + ${geometry_msgs_ASSEMBLIES_DLL} + ${test_msgs_ASSEMBLIES_DLL} + ${action_msgs_ASSEMBLIES_DLL} + ${ilabos_msgs_ASSEMBLIES_DLL} + ${YAMLDOTNET_DLL} +) + +add_dotnet_executable(ros_driver + Program.cs + DeviceNode.cs + DeviceActionServer.cs + PropertyPublisher.cs + MockGripper.cs + utils/Yaml.cs + utils/MessageConverter.cs + INCLUDE_DLLS + ${_assemblies_dep_dlls} +) + + +install_dotnet(ros_driver DESTINATION lib/${PROJECT_NAME}/dotnet) + + +ament_package() \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/DeviceActionServer.cs b/ros2_csharp/src/ros_driver/DeviceActionServer.cs new file mode 100644 index 00000000..907f9ec8 --- /dev/null +++ b/ros2_csharp/src/ros_driver/DeviceActionServer.cs @@ -0,0 +1,133 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using ROS2; +using test_msgs.action; +using System.Collections.Generic; +using ilabos_msgs.action; +using RosDriver.Utils; + +namespace ros_driver +{ + /// + /// Generic action server that can be used with any ROS2 action type + /// + public class DeviceActionServer : IDisposable + where TAction : IRosActionDefinition + where TGoal : IRosMessage, new() + where TResult : IRosMessage, new() + where TFeedback : IRosMessage, new() + { + private readonly Node _node; + private readonly string _actionName; + private bool _disposed = false; + private ActionValueMapping _actionValue = null; + private readonly object _device = null; + + + public DeviceActionServer( + Node node, + object device, + string actionName, + ActionValueMapping actionValue) + { + _node = node; + _actionName = actionName; + _actionValue = actionValue; + _device = device; + + _node.CreateActionServer( + _actionName, + HandleAccepted, + cancelCallback: HandleCancel); + + Console.WriteLine($"Created Action Server: {_actionName}"); + } + + + private void HandleAccepted(ActionServerGoalHandle goalHandle) + { + // Don't block in the callback. + // -> Don't wait for the returned Task. + _ = DoWorkWithGoal(goalHandle); + } + + private CancelResponse HandleCancel(ActionServerGoalHandle goalHandle) + { + return CancelResponse.Accept; + } + + private async Task DoWorkWithGoal(ActionServerGoalHandle goalHandle) + { + + Console.WriteLine("Executing goal..."); + // 检查 TAction 是否是 Fibonacci 类型 + if (typeof(TAction) == typeof(Fibonacci)) + { + Console.WriteLine("确认 TAction 是 Fibonacci 类型"); + // 注意:这种转换是不安全的,因为泛型参数在编译时已确定 + // 这里仅作为示例,实际使用时需要谨慎 + var fibonacciGoalHandle = goalHandle as ActionServerGoalHandle; + if (fibonacciGoalHandle != null) + { + Console.WriteLine("成功转换为 Fibonacci 类型的 GoalHandle"); + var feedback = new Fibonacci_Feedback(); + + feedback.Sequence = new List { 0, 1 }; + + for (int i = 1; i < fibonacciGoalHandle.Goal.Order; i++) + { + if (fibonacciGoalHandle.IsCanceling) + { + var cancelResult = new Fibonacci_Result(); + cancelResult.Sequence = feedback.Sequence; + + Console.WriteLine($"Canceled Result: {string.Join(", ", cancelResult.Sequence)}"); + fibonacciGoalHandle.Canceled(cancelResult); + return; + } + + feedback.Sequence.Add(feedback.Sequence[i] + feedback.Sequence[i - 1]); + + Console.WriteLine($"Feedback: {string.Join(", ", feedback.Sequence)}"); + fibonacciGoalHandle.PublishFeedback(feedback); + + // NOTE: This causes the code to resume in an background worker Thread. + // Consider this when copying code from the example if additional synchronization is needed. + await Task.Delay(1000); + } + + var result = new Fibonacci_Result(); + result.Sequence = feedback.Sequence; + + Console.WriteLine($"Result: {string.Join(", ", result.Sequence)}"); + fibonacciGoalHandle.Succeed(result); + } + } + else + { + Console.WriteLine($"TAction 不是 Fibonacci 类型,而是 {typeof(TAction).Name}"); + return; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Release managed resources if any + } + + _disposed = true; + } + } + } +} diff --git a/ros2_csharp/src/ros_driver/DeviceNode.cs b/ros2_csharp/src/ros_driver/DeviceNode.cs new file mode 100644 index 00000000..aca65281 --- /dev/null +++ b/ros2_csharp/src/ros_driver/DeviceNode.cs @@ -0,0 +1,173 @@ +using System; +using System.Threading.Tasks; +using ROS2; +using test_msgs.action; +using System.Collections.Generic; +using RosDriver.Utils; +using System.Reflection; + + +namespace ros_driver +{ + class DeviceNode : IDisposable + { + private readonly Node _node; + private readonly object _device; + private readonly string _name; + private bool _disposed = false; + + private readonly Dictionary _propertyPublishers = new Dictionary(); + private readonly Dictionary _actionServers = new Dictionary(); + + public DeviceNode(Node node, string name, DeviceInfo deviceInfo) + { + _name = name; + _node = node; + + _device = new MockGripper(); + Type dType = _device.GetType(); + PropertyInfo[] properties = dType.GetProperties( + BindingFlags.Public | BindingFlags.Instance); + + var statusTypes = deviceInfo.StatusTypes; + var actionMappings = deviceInfo.ActionValueMappings; + foreach (var prop in properties) + { + MethodInfo setMethod = prop.GetSetMethod(nonPublic: true); + MethodInfo getMethod = prop.GetGetMethod(nonPublic: true); + + // 如果 setMethod 不是 null 打印方法名和返回值名 + if (setMethod != null) + { + ParameterInfo[] parameters = setMethod.GetParameters(); + Type parameterType = parameters[0].ParameterType; + + // 如果返回值是字符串,则actionMappings 添加一个 ActionValueMapping 对象 + if (setMethod.ReturnType == typeof(string)) + { + var actionValueMapping = new ActionValueMapping + { + Type = "SendCmd", + Goal = new Dictionary { { "command", parameterType.Name } }, + Feedback = new Dictionary { { "status", "status" } }, + Result = new Dictionary(), + }; + actionMappings.Add(prop.Name, new ActionValueMapping()); + } + Console.WriteLine($"Property: {prop.Name}, Setter: {setMethod.Name},Parameter Type: {parameterType.Name}, Return Type: {setMethod.ReturnType.Name}"); + } + + // 如果 getMethod 不是 null 打印方法名和返回值名 + if (getMethod != null) + { + // 判断 prop.Name 不在 statusTypes 中,则添加到 statusTypes 中 + if (!statusTypes.ContainsKey(prop.Name)) + { + statusTypes.Add(prop.Name, getMethod.ReturnType.Name); + } + Console.WriteLine($"Property: {prop.Name}, Getter: {getMethod.Name}, Return Type: {getMethod.ReturnType.Name}"); + } + } + + foreach (var kv in statusTypes) + { + Console.WriteLine($"create publisher: {kv.Key}:"); + CreatePublisher(kv.Key, kv.Value); + } + + foreach (var kv in actionMappings) + { + Console.WriteLine($"create action server: {kv.Key}:"); + CreateActionServer(kv.Key, kv.Value); + } + } + + private void CreatePublisher(string key, string msgType) + { + Type rosMessageType = Converter2RosMessage.GetRosMessageType(msgType); + + // Use reflection to create the appropriate publisher type + var publisherType = typeof(PropertyPublisher<>).MakeGenericType(rosMessageType); + var publisher = Activator.CreateInstance(publisherType, _node, _device, key, 1.0, true); + _propertyPublishers.Add(key, publisher); + } + + private void CreateActionServer(string key, ActionValueMapping actionValue) + { + try + { + List actionTypes = Converter2RosMessage.GetActionMessageType(actionValue.Type); + if (actionTypes.Count != 4) + { + throw new ArgumentException($"Expected 4 action types, but got {actionTypes.Count} for action {actionValue.Type}"); + } + + // 提取类型:Action, Goal, Result, Feedback + Type actionType = actionTypes[0]; + Type goalType = actionTypes[1]; + Type resultType = actionTypes[2]; + Type feedbackType = actionTypes[3]; + + // 使用反射创建正确泛型类型的DeviceActionServer + Type deviceActionServerType = typeof(DeviceActionServer<,,,>).MakeGenericType( + actionType, goalType, resultType, feedbackType); + + // 创建DeviceActionServer实例 + object actionServer = Activator.CreateInstance( + deviceActionServerType, + _node, // 节点 + _device, // 设备对象 + key, // 动作名称 + actionValue // 动作值映射 + ); + + // 将动作服务器存储在字典中 + _actionServers.Add(key, actionServer); + + Console.WriteLine($"成功创建了类型为 {actionValue.Type} 的动作服务器 {key}"); + } + catch (Exception ex) + { + Console.WriteLine($"创建动作服务器 {key} 时出错: {ex.Message}"); + if (ex.InnerException != null) + { + Console.WriteLine($"内部异常: {ex.InnerException.Message}"); + } + Console.WriteLine($"这可能是由于消息定义中缺少或不正确的类型支持。"); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Node doesn't have a Dispose method, so don't try to call it + // _node.Dispose(); + + // Handle other resources that need to be released + foreach (var publisher in _propertyPublishers.Values) + { + if (publisher is IDisposable disposable) + disposable.Dispose(); + } + + foreach (var server in _actionServers.Values) + { + if (server is IDisposable disposable) + disposable.Dispose(); + } + } + // Dispose unmanaged resources if any + _disposed = true; + } + } + } +} \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/MockGripper.cs b/ros2_csharp/src/ros_driver/MockGripper.cs new file mode 100644 index 00000000..e709d186 --- /dev/null +++ b/ros2_csharp/src/ros_driver/MockGripper.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; + +public class MockGripper +{ + private double _position = 0.0; + public double Position + { + get + { + _position += 1.0; + return _position; + } + private set + { + _position = value; + } + } + + private double _velocity = 2.0; + public double Velocity + { + get + { + _velocity += 1.0; + return _velocity; + } + private set + { + _velocity = value; + } + } + + private double _torque = 0.0; + public double Torque + { + get + { + _torque += 1.0; + return _torque; + } + private set + { + _torque = value; + } + } + + public string Status { get; private set; } = "Idle"; + + public async Task PushToAsync(double position, double torque, double velocity = 0.0) + { + Status = "Running"; + double currentPos = Position; + + if (velocity == 0.0) + { + velocity = Velocity; + } + + double moveTime = Math.Abs(position - currentPos) / velocity; + + for (int i = 0; i < 20; i++) + { + Position = currentPos + (position - currentPos) / 20 * (i + 1); + Torque = torque / (20 - i); + Velocity = velocity; + await Task.Delay((int)(moveTime * 1000 / 20)); // Convert seconds to milliseconds + } + + Torque = torque; + Status = "Idle"; + } +} \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/Program.cs b/ros2_csharp/src/ros_driver/Program.cs new file mode 100644 index 00000000..487a54f5 --- /dev/null +++ b/ros2_csharp/src/ros_driver/Program.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ROS2; +using RosDriver.Utils; + +namespace ros_driver +{ + class Program + { + private static void Main(string[] args) + { + RCLdotnet.Init(); + + // Get device configuration from environment variables + string configFilePath = Environment.GetEnvironmentVariable("CONFIG_FILE_PATH"); + if (string.IsNullOrEmpty(configFilePath)) + { + Console.WriteLine("Please set the CONFIG_FILE_PATH environment variable."); + return; + } + + var deviceDict = YamlConfigParser.GetDeviceInfoDict(configFilePath); + + // 创建列表存储所有节点和设备对象 + List nodes = new List(); + List deviceNodes = new List(); + + foreach (var device in deviceDict) + { + string deviceId = device.Key; + DeviceInfo deviceInfo = device.Value; + string nodeName = deviceId.Split('/').Last(); + string nodeNamespace = $"/devices/{deviceId}"; + + Console.WriteLine($"Starting node '{nodeName}' with namespace '{nodeNamespace}'"); + Console.WriteLine($"Using config file: {configFilePath}"); + + var node = RCLdotnet.CreateNode(nodeName, nodeNamespace); + var deviceNode = new DeviceNode(node, deviceId, deviceInfo); + + // 添加到列表中而不是立即spin + nodes.Add(node); + deviceNodes.Add(deviceNode); + } + + while (RCLdotnet.Ok()) + { + foreach (var node in nodes) + { + RCLdotnet.SpinOnce(node, 100); // 100ms超时 + } + } + + // 清理资源 + foreach (var deviceNode in deviceNodes) + { + deviceNode.Dispose(); + } + + RCLdotnet.Shutdown(); + } + } +} \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/PropertyPublisher.cs b/ros2_csharp/src/ros_driver/PropertyPublisher.cs new file mode 100644 index 00000000..12ca3286 --- /dev/null +++ b/ros2_csharp/src/ros_driver/PropertyPublisher.cs @@ -0,0 +1,217 @@ +using System; +using System.Threading.Tasks; +using ROS2; +using test_msgs.action; +using System.Reflection; +using RosDriver.Utils; + + + +namespace ros_driver +{ + /// + /// A publisher that periodically publishes property values as ROS messages + /// + public class PropertyPublisher where T : IRosMessage, new() + { + private readonly Node _node; + private readonly string _name; + private readonly bool _printPublish; + private readonly object _device = null; + + private T _value; + private Publisher _publisher; + private Timer _timer; + private TimeSpan _timerPeriod; + + + public PropertyPublisher( + Node node, + object device, + string name, + double initialPeriod = 1.0, + bool printPublish = true) + { + _node = node; + _device = device; + _name = name; + _timerPeriod = TimeSpan.FromSeconds(initialPeriod); + _printPublish = printPublish; + + _publisher = node.CreatePublisher(_name); + _timer = node.CreateTimer(_timerPeriod, PublishProperty); + + Console.WriteLine($"创建发布者 {name}, {typeof(T)}"); + + _value = new T(); + InitializeValue(); + } + + private void InitializeValue() + { + if (_value is std_msgs.msg.String strData) + { + strData.Data = "hello world"; + } + + if (_value is std_msgs.msg.Int32 intData) + { + intData.Data = 1; + } + + if (_value is std_msgs.msg.Float64 floatData) + { + floatData.Data = 1.00f; + } + + if (_value is std_msgs.msg.Float64MultiArray floatArrayData) + { + floatArrayData.Data = new System.Collections.Generic.List { 1.0, 2.0, 3.0, 4.0 }; + floatArrayData.Layout = new std_msgs.msg.MultiArrayLayout(); + } + } + + private bool HasMethod(object obj, string methodName) + { + if (obj == null) + return false; + + Type type = obj.GetType(); + return type.GetMethod(methodName) != null; + } + + // 检查对象是否有特定名称的属性 + private bool HasProperty(object obj, string propertyName) + { + if (obj == null) + return false; + + Type type = obj.GetType(); + return type.GetProperty(propertyName) != null; + } + + public object SafeGetPropertyValue(string propertyName) + { + if (!HasProperty(_device, propertyName)) + { + return null; // 或抛出异常,或返回默认值 + } + + PropertyInfo propInfo = _device.GetType().GetProperty(propertyName); + MethodInfo getMethod = propInfo.GetGetMethod(nonPublic: true); + + if (getMethod == null) + return null; // 没有 getter 方法 + + return getMethod.Invoke(_device, null); + } + + private T getProperty() + { + + var result = SafeGetPropertyValue(_name); + if (result != null) + { + Console.WriteLine($"level: info, Property '{_name}' not found in device '{_device.GetType().Name}', result: {result}"); + return Converter2RosMessage.ConvertToRosMessage(result); + } + + return mockData(); + } + + private T mockData() + { + // Get the full name with namespace + string typeName = typeof(T).FullName; + + if (typeName.EndsWith(".Float64")) + return Converter2RosMessage.ConvertToRosMessage(1.0); + else if (typeName.EndsWith(".String")) + return Converter2RosMessage.ConvertToRosMessage("hello world"); + else if (typeName.EndsWith(".Int32")) + return Converter2RosMessage.ConvertToRosMessage(1); + else if (typeName.EndsWith(".Float64MultiArray")) + return Converter2RosMessage.ConvertToRosMessage(new double[] { 1.0, 2.0, 3.0, 4.0 }); + else + throw new NotSupportedException($"Type {typeName} is not supported."); + } + + + private async Task getPropertyAsync() + { + await Task.Yield(); + var result = SafeGetPropertyValue(_name); + if (result != null) + { + // Console.WriteLine($"level: info, Property '{_name}' found in device '{_device.GetType().Name}', result: {result}"); + return Converter2RosMessage.ConvertToRosMessage(result); + } + return mockData(); + } + + /// + /// Gets the property value synchronously + /// + /// The property value + public T GetProperty() + { + + // If async method is available, run it on a task and wait for result + return Task.Run(async () => await getPropertyAsync()).Result; + + + // // Otherwise call the synchronous method + // return getProperty(); + } + + + /// + /// Publishes the property value + /// + private void PublishProperty(TimeSpan elapsed) + { + try + { + T value = GetProperty(); + if (_printPublish) + { + //_node.Logger.Info($"Publishing {typeof(T).Name}: {value}"); + Console.WriteLine($"level: info,prop name: {_name}, {typeof(T).Name}: {value} normal msg: {Converter2RosMessage.ConvertFromRosMessage(value)}"); + } + + if (value != null) + { + // Console.WriteLine($"level: info, Publishing type: {typeof(T)}, value: {value.Data}"); + _publisher.Publish(value); + } + } + catch (Exception ex) + { + //_node.Logger.Error($"Error in PublishProperty: {ex.Message}\n{ex.StackTrace}"); + Console.WriteLine($"level: error, PublishProperty: {ex.Message}\n{ex.StackTrace}"); + } + } + + + + + + + + /// + /// Changes the frequency of publication + /// + /// New period in seconds + public void ChangeFrequency(double period) + { + _timerPeriod = TimeSpan.FromSeconds(period); + // _node.Logger.Info($"Changing {_name} timer period to: {_timerPeriod.TotalSeconds} seconds"); + Console.WriteLine($"level: info, Changing {_name} timer period to: {_timerPeriod.TotalSeconds} seconds"); + + + // Reset timer + _timer.Cancel(); + _timer = _node.CreateTimer(_timerPeriod, PublishProperty); + } + } +} diff --git a/ros2_csharp/src/ros_driver/deps/YamlDotNet/YamlDotNet.dll b/ros2_csharp/src/ros_driver/deps/YamlDotNet/YamlDotNet.dll new file mode 100644 index 0000000000000000000000000000000000000000..41ad720870bdc7f69017f6fd8fad3924236e48ec GIT binary patch literal 292352 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
NyFzLgj50k!~TDwb~?tY7U=Pi== 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 + + ros_driver + 0.0.0 + Package containing examples of how to use the rcldotnet API. + Esteve Fernandez + Apache License 2.0 + + ament_cmake + ament_cmake_export_assemblies + + dotnet_cmake_module + rcldotnet_common + rosidl_cmake + + builtin_interfaces + example_interfaces + rcldotnet + std_msgs + std_srvs + sensor_msgs + test_msgs + ilabos_msgs + + rcldotnet_common + builtin_interfaces + example_interfaces + rcldotnet + std_msgs + std_srvs + sensor_msgs + test_msgs + ilabos_msgs + + + ament_cmake + + diff --git a/ros2_csharp/src/ros_driver/utils/MessageConverter.cs b/ros2_csharp/src/ros_driver/utils/MessageConverter.cs new file mode 100644 index 00000000..4afde2b7 --- /dev/null +++ b/ros2_csharp/src/ros_driver/utils/MessageConverter.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using ROS2; +using test_msgs.action; +using builtin_interfaces.msg; +using ilabos_msgs.action; + +namespace RosDriver.Utils +{ + // 静态方法1 C# 根据数据std_msg.msg 类型把数据转 std_msg.msg 类型数据。 + + public static class Converter2RosMessage + { + + // 帮我写一个静态函数,接受一个 string 返回一个 std_msgs.msg 类型,例如接受 String 返回 std_msgs.msg.String 类型,而不是具体的实例 + public static Type GetRosMessageType(string typeName) + { + return typeName switch + { + "String" => typeof(std_msgs.msg.String), + "Int32" => typeof(std_msgs.msg.Int32), + "Float32" => typeof(std_msgs.msg.Float32), + "Float64" => typeof(std_msgs.msg.Float64), + "Double" => typeof(std_msgs.msg.Float64), + "Bool" => typeof(std_msgs.msg.Bool), + "Byte" => typeof(std_msgs.msg.Byte), + "Float64MultiArray" => typeof(std_msgs.msg.Float64MultiArray), + _ => throw new ArgumentException($"Unsupported type name: {typeName}", nameof(typeName)) + }; + } + + // 根据名字返回类型,例如Fibonacci 字符串就返回四个类型 Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback + public static List GetActionMessageType(string typeName) + { + switch (typeName) + { + case "Fibonacci": + return new List { typeof(Fibonacci), typeof(Fibonacci_Goal), typeof(Fibonacci_Result), typeof(Fibonacci_Feedback) }; + case "SendCmd": + return new List { typeof(SendCmd), typeof(SendCmd_Goal), typeof(SendCmd_Result), typeof(SendCmd_Feedback) }; + case "Stir": + return new List { typeof(Stir), typeof(Stir_Goal), typeof(Stir_Result), typeof(Stir_Feedback) }; + case "HeatChill": + return new List { typeof(HeatChill), typeof(HeatChill_Goal), typeof(HeatChill_Result), typeof(HeatChill_Feedback) }; + default: + throw new ArgumentException($"Unsupported type name: {typeName}", nameof(typeName)); + } + } + + + // 新增方法: 使用 switch type 识别不同类型的数据并转换为对应的 std_msgs.msg 类型 + public static T ConvertToRosMessage(object data) where T : IRosMessage, new() + { + T rosMessage = new T(); + + switch (rosMessage) + { + case std_msgs.msg.String stringMsg when data is string strData: + stringMsg.Data = strData; + return rosMessage; + + case std_msgs.msg.Int32 int32Msg when data is int intData: + int32Msg.Data = intData; + return rosMessage; + + case std_msgs.msg.Float32 float32Msg when data is float floatData: + float32Msg.Data = floatData; + return rosMessage; + + case std_msgs.msg.Float64 float64Msg when data is double doubleData: + float64Msg.Data = doubleData; + return rosMessage; + + case std_msgs.msg.Bool boolMsg when data is bool boolData: + boolMsg.Data = boolData; + return rosMessage; + + case std_msgs.msg.Byte byteMsg when data is byte byteData: + byteMsg.Data = byteData; + return rosMessage; + + case std_msgs.msg.Char charMsg when data is char charData: + charMsg.Data = (byte)charData; + return rosMessage; + + case std_msgs.msg.ByteMultiArray byteArrayMsg when data is byte[] byteArrayData: + byteArrayMsg.Data = byteArrayData.ToList(); + byteArrayMsg.Layout = new std_msgs.msg.MultiArrayLayout(); + return rosMessage; + + case std_msgs.msg.Float64MultiArray float64ArrayMsg when data is double[] doubleArrayData: + float64ArrayMsg.Data = doubleArrayData.ToList(); + float64ArrayMsg.Layout = new std_msgs.msg.MultiArrayLayout(); + return rosMessage; + + case std_msgs.msg.Float64MultiArray float64ArrayMsg when data is List doubleListData: + float64ArrayMsg.Data = doubleListData; + float64ArrayMsg.Layout = new std_msgs.msg.MultiArrayLayout(); + return rosMessage; + + case builtin_interfaces.msg.Time timeMsg when data is DateTime dateTimeData: + timeMsg.Sec = (int)(dateTimeData.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + timeMsg.Nanosec = (uint)(dateTimeData.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).Milliseconds * 1000000; + return rosMessage; + + case builtin_interfaces.msg.Duration durationMsg when data is TimeSpan timeSpanData: + durationMsg.Sec = (int)timeSpanData.TotalSeconds; + durationMsg.Nanosec = (uint)(timeSpanData.Milliseconds * 1000000); + return rosMessage; + + default: + throw new InvalidOperationException( + $"Cannot convert data of type '{data.GetType().Name}' to ROS message type '{typeof(T).Name}'"); + } + } + + // 将ROS消息转换回C#数据类型的方法 + public static object ConvertFromRosMessage(IRosMessage rosMessage) + { + return rosMessage switch + { + std_msgs.msg.String strMsg => strMsg.Data, + std_msgs.msg.Int32 int32Msg => int32Msg.Data, + std_msgs.msg.Float32 float32Msg => float32Msg.Data, + std_msgs.msg.Float64 float64Msg => float64Msg.Data, + std_msgs.msg.Bool boolMsg => boolMsg.Data, + std_msgs.msg.Byte byteMsg => byteMsg.Data, + std_msgs.msg.Char charMsg => charMsg.Data, + std_msgs.msg.ByteMultiArray byteArrayMsg => byteArrayMsg.Data, + std_msgs.msg.Float64MultiArray float64ArrayMsg => float64ArrayMsg.Data, + builtin_interfaces.msg.Time timeMsg => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) + .AddSeconds(timeMsg.Sec) + .AddMilliseconds(timeMsg.Nanosec / 1000000.0), + builtin_interfaces.msg.Duration durationMsg => TimeSpan.FromSeconds(durationMsg.Sec) + .Add(TimeSpan.FromMilliseconds(durationMsg.Nanosec / 1000000.0)), + // 可以根据需要添加更多类型的匹配 + _ => throw new ArgumentException($"Unsupported ROS message type: {rosMessage.GetType().Name}", nameof(rosMessage)) + }; + } + + // 泛型版本,当客户端代码知道期望的返回类型时使用 + public static T ConvertFromRosMessage(IRosMessage rosMessage) + { + object result = ConvertFromRosMessage(rosMessage); + if (result is T typedResult) + { + return typedResult; + } + throw new InvalidCastException($"Cannot convert from {rosMessage.GetType().Name} to {typeof(T).Name}"); + } + } +} \ No newline at end of file diff --git a/ros2_csharp/src/ros_driver/utils/Yaml.cs b/ros2_csharp/src/ros_driver/utils/Yaml.cs new file mode 100644 index 00000000..fceb8880 --- /dev/null +++ b/ros2_csharp/src/ros_driver/utils/Yaml.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; +using YamlDotNet.RepresentationModel; + +namespace RosDriver.Utils +{ + public class ActionValueMapping + { + public string Type { get; set; } + public Dictionary Goal { get; set; } + public Dictionary Feedback { get; set; } + public Dictionary Result { get; set; } + + public ActionValueMapping() + { + Goal = new Dictionary(); + Feedback = new Dictionary(); + Result = new Dictionary(); + } + } + + public class DeviceInfo + { + public Dictionary StatusTypes { get; set; } + public Dictionary ActionValueMappings { get; set; } + + public DeviceInfo() + { + StatusTypes = new Dictionary(); + ActionValueMappings = new Dictionary(); + } + } + + public class YamlConfigParser + { + + private static void ExtractMappingSection(YamlMappingNode parentNode, string sectionName, Dictionary targetDict) + { + var sectionKeyNode = new YamlScalarNode(sectionName); + if (parentNode.Children.ContainsKey(sectionKeyNode)) + { + var sectionNode = parentNode.Children[sectionKeyNode] as YamlMappingNode; + if (sectionNode != null) + { + foreach (var entry in sectionNode.Children) + { + if (entry.Key is YamlScalarNode entryKeyNode && + entry.Value is YamlScalarNode entryValueNode) + { + targetDict[entryKeyNode.Value] = entryValueNode.Value; + } + } + } + } + } + + private static Dictionary ParseDeviceInfo(string filePath) + { + var devices = new Dictionary(); + + using (var reader = new StreamReader(filePath)) + { + var yaml = new YamlStream(); + yaml.Load(reader); + + var rootNode = yaml.Documents[0].RootNode as YamlMappingNode; + if (rootNode == null) + { + throw new InvalidDataException("Root node is not a mapping node."); + } + + foreach (var deviceEntry in rootNode.Children) + { + var deviceKey = ((YamlScalarNode)deviceEntry.Key).Value; + var deviceNode = deviceEntry.Value as YamlMappingNode; + if (deviceNode == null) continue; + + var deviceInfo = new DeviceInfo(); + + // Parse status_types + YamlMappingNode classMappingNode = null; + if (deviceNode.Children.TryGetValue(new YamlScalarNode("class"), out var classNode) && + classNode is YamlMappingNode tempClassNode) + { + classMappingNode = tempClassNode; + if (classMappingNode.Children.TryGetValue(new YamlScalarNode("status_types"), out var statusTypesNode) && + statusTypesNode is YamlMappingNode statusTypesMappingNode) + { + foreach (var statusEntry in statusTypesMappingNode.Children) + { + var key = ((YamlScalarNode)statusEntry.Key).Value; + var value = ((YamlScalarNode)statusEntry.Value).Value; + deviceInfo.StatusTypes[key] = value; + } + } + } + + // Parse action_value_mappings + if (classMappingNode != null && + classMappingNode.Children.TryGetValue(new YamlScalarNode("action_value_mappings"), out var actionMappingsNode) && + actionMappingsNode is YamlMappingNode actionMappingsMappingNode) + { + foreach (var actionEntry in actionMappingsMappingNode.Children) + { + var actionKey = ((YamlScalarNode)actionEntry.Key).Value; + var actionNode = actionEntry.Value as YamlMappingNode; + if (actionNode == null) continue; + + var actionValue = new ActionValueMapping(); + + // Extract type + if (actionNode.Children.TryGetValue(new YamlScalarNode("type"), out var typeNode) && + typeNode is YamlScalarNode typeScalarNode) + { + actionValue.Type = typeScalarNode.Value; + } + + // Extract goal, feedback, result + ExtractMappingSection(actionNode, "goal", actionValue.Goal); + ExtractMappingSection(actionNode, "feedback", actionValue.Feedback); + ExtractMappingSection(actionNode, "result", actionValue.Result); + + deviceInfo.ActionValueMappings[actionKey] = actionValue; + } + } + + devices[deviceKey] = deviceInfo; + } + } + + return devices; + } + + public static Dictionary GetDeviceInfoDict(string filePath) + { + return ParseDeviceInfo(filePath); + } + } +}