把controller分成group 之后 link_to出现奇怪问题

在Rails项目中,为了更好地组织控制器,创建了额外的文件夹来存放特定类别的控制器。然而,在使用链接导航到这些控制器的动作时遇到了路由问题,尤其是在Internet Explorer浏览器中。
在作一个项目,controller folder 下的各种各样的controller比较多。很乱。
于是新建了几个folder把属于一类的controller 放在一起。
例如就像typo里面那个admin folder一样。
controller(folder) -->welcome_controller.rb
-->admin(folder) --->accounts_controller.rb


可是出现了奇怪的问题。
在一个页面里,比如说有3个link_to生成的link. A B C
其中 A, B 都是link到普通的controller 里面的action.
C 连接到 admin 文件夹下面的controller 里面的action.


<%= link_to 'A', :controller=> 'welcome', :action=>'A'%>
<%= link_to 'B', :controller=> 'welcome', :action=>'B'%>
<%= link_to 'C', :controller=> 'admin/accounts', :action=>'C'%>


问题是:在不点击link C 之前,Link A,B 工作正常。
只要点击了link C 之后,Link A,B 生成的url就变了。
http://localhost:3000/admin/welcome/A

当然,并没有这个page.会出现routing error.
我开始想可能是因为相对路径的问题。

于是解决方法是把link A, B 改成
<%= link_to 'A', :controller=> '../welcome', :action=>'A'%>

之后问题得到初步解决。
无论以什么顺序点击link ABC都没有错误(在firefox 中)。

因为我一直都用firefox + firebug,所以很少用IE。
谁知道在IE 下面问题还不小呢。

问题是:Link C 工作正常。
Link A,B 生成的url就变了。
http://localhost:3000/../welcome/A

此时会出现routing error.


试图找到问题的根源,但是没发现什么特殊的。
不知道大家有没有类似经历,可以给我点启发。
谢谢
[ERROR] [1765200668.587827072, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/left_wheel2base_link/set_parameters] [ERROR] [1765200668.595697897, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/right_wheel2base_link/set_parameters] [ERROR] [1765200668.607726634, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/front_wheel2base_link/set_parameters] [ERROR] [1765200668.618785666, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/back_wheel2base_link/set_parameters] [ERROR] [1765200668.629634551, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/list_controllers] [ERROR] [1765200668.629824071, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/list_controller_types] [ERROR] [1765200668.629847533, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/load_controller] [ERROR] [1765200668.629897291, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/unload_controller] [ERROR] [1765200668.629921218, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/switch_controller] [ERROR] [1765200668.629946964, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/reload_controller_libraries] [INFO] [1765200668.630198451, 257.830000000]: Loaded gazebo_ros_control. [INFO] [1765200668.630524192, 257.830000000]: Loading gazebo_ros_control plugin [INFO] [1765200668.630559722, 257.830000000]: Starting gazebo_ros_control plugin in namespace: / [ERROR] [1765200668.738247589, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/left_wheel2base_link/set_parameters] [INFO] [1765200668.740894, 257.830000]: Controller Spawner: Waiting for service controller_manager/switch_controller [INFO] [1765200668.742798, 257.830000]: Controller Spawner: Waiting for service controller_manager/unload_controller [INFO] [1765200668.743176, 257.830000]: Controller Spawner: Waiting for service controller_manager/switch_controller [INFO] [1765200668.744603, 257.830000]: Loading controller: joint_state_controller [INFO] [1765200668.745332, 257.830000]: Controller Spawner: Waiting for service controller_manager/unload_controller [INFO] [1765200668.747757, 257.830000]: Loading controller: joint_group_eff_controller [INFO] [1765200668.753925, 257.830000]: Loading controller: eff_joint_traj_controller [ERROR] [1765200668.754961647, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/right_wheel2base_link/set_parameters] [INFO] [1765200668.762208, 257.830000]: Controller Spawner: Loaded controllers: joint_group_eff_controller [ERROR] [1765200668.768643455, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/front_wheel2base_link/set_parameters] [ERROR] [1765200668.785391858, 257.830000000]: Tried to advertise a service that is already advertised in this node [/gazebo_ros_control/pid_gains/back_wheel2base_link/set_parameters] [ERROR] [1765200668.808047841, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/list_controllers] [ERROR] [1765200668.808409818, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/list_controller_types] [ERROR] [1765200668.809248185, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/load_controller] [ERROR] [1765200668.809461158, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/unload_controller] [ERROR] [1765200668.809695297, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/switch_controller] [ERROR] [1765200668.810079590, 257.830000000]: Tried to advertise a service that is already advertised in this node [/controller_manager/reload_controller_libraries]
最新发布
12-09
<think>我们当前需要解决两个主要问题: 1. ROS节点中出现的服务重复广告错误:Tried to advertise a service that is already advertised in this node 2. 之前遇到的CMake配置不完整、调用失败的问题(如Gazebo相关包弃用导致的编译错误) 根据引用[1]和[2],服务重复广告错误通常是因为在同一个节点中多次调用`ros::NodeHandle::advertiseService()`或`ros::ServiceServer`创建了同名的服务。而引用[3][4][5]则提供了编译和运行Kinect2相关节点的过程,可能涉及到依赖和编译问题。 我们将分别给出解决方案。 一、解决服务重复广告错误(Tried to advertise a service that is already advertised in this node) 此错误通常发生在以下情况: - 在同一个节点中,多次为同一个服务名称创建了服务服务器(service server)。 - 在类的构造函数中创建服务,而该类的对象被多次实例化,但使用的是同一个节点句柄(NodeHandle)。 解决方法: 1. 检查代码中是否有重复创建同名服务的情况。确保对于同一个服务名称,只调用一次`advertiseService`。 2. 如果使用C++类,确保在类的构造函数中创建服务时,该类不会被多次实例化(比如单例模式)或者确保服务名称唯一。 3. 如果同一个节点需要提供多个参数动态配置服务(如使用`rqt_reconfigure`),请确保每个`reconfigure`实例使用不同的命名空间或者合并到一个配置中。 引用[2]中提到的问题是因为在同一个节点中尝试为两组参数动态调参,但使用了相同的服务名称`/robot_chassis_node/set_parameters`。解决方法: - 将两组参数合并到一个配置文件中,这样只需要一个动态参数服务器。 - 或者将这两组参数放在不同的命名空间下,例如: ```cpp dynamic_reconfigure::Server<robot_chassis::Config1> server1; dynamic_reconfigure::Server<robot_chassis::Config2> server2; ``` 然后通过不同的回调函数处理。 二、解决CMake配置不完整、调用失败的问题 根据之前的对话,CMake配置失败主要是因为Gazebo相关包弃用导致找不到包。但当前用户还提到了引用[4]中关于OpenCL缺失的报错,以及引用[3][5]中关于Kinect2的编译问题。因此,我们可能需要解决多个依赖问题。 1. 解决Gazebo相关包弃用问题(已在之前回答中给出,但这里再总结): - 确保安装了正确版本的`gazebo_ros_pkgs`: ```bash sudo apt-get install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros-control ``` - 在`package.xml`中添加依赖: ```xml <depend>gazebo_ros</depend> <depend>gazebo_plugins</depend> <depend>gazebo_ros_control</depend> ``` - 在`CMakeLists.txt`中正确引入: ```cmake find_package(catkin REQUIRED COMPONENTS gazebo_ros gazebo_ros_control gazebo_plugins # ... 其他组件 ) ``` 2. 解决OpenCL缺失问题(引用[4]): 报错信息: ``` Could NOT find OpenCL (missing: OpenCL_LIBRARY OpenCL_INCLUDE_DIR) (Required is at least version "2") ``` 解决方法: - 安装OpenCL开发包: ```bash sudo apt install ocl-icd-opencl-dev ``` - 如果上述包不能满足版本要求,可以尝试安装其他实现,如: ```bash sudo apt install beignet-dev # 对于Intel集成显卡 # 或者 sudo apt install nvidia-opencl-dev # 对于NVIDIA显卡 ``` 3. 编译Kinect2相关包(引用[3][5]): - 确保按照步骤安装依赖: ```bash cd ~/ROS/iai_kinect2 rosdep install -r --from-paths . ``` - 编译时指定构建类型(Release): ```bash catkin_make -DCMAKE_BUILD_TYPE="Release" ``` - 如果遇到权限问题,可能需要给脚本添加执行权限: ```bash cd ~/ROS/iai_kinect2/src/iai_kinect2/kinect2_bridge chmod +x kinect2_bridge ``` 三、综合步骤 如果用户同时遇到以上问题,建议按照以下步骤操作: 步骤1:解决依赖问题 - 安装Gazebo相关包和OpenCL开发包: ```bash sudo apt-get update sudo apt-get install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros-control sudo apt install ocl-icd-opencl-dev # 根据显卡选择安装,例如NVIDIA显卡: sudo apt install nvidia-opencl-dev ``` 步骤2:修复代码中的服务重复广告问题 - 检查代码,确保同一服务名称只被广告一次。 步骤3:重新编译工作空间 - 清理工作空间并重新编译: ```bash cd ~/catkin_ws rm -rf build devel catkin_make -DCMAKE_BUILD_TYPE=Release source devel/setup.bash ``` 步骤4:运行测试 - 运行节点,检查服务重复广告错误是否解决。 - 运行Gazebo或Kinect2节点,检查功能是否正常。 四、相关问题生成 根据以上内容,生成相关问题: </think> ### 解决 ROS 服务重复广告错误与 CMake 编译问题 #### 一、解决服务重复广告错误 `Tried to advertise a service that is already advertised` 此错误发生在同一个节点中尝试重复注册同名服务时,常见于动态参数配置场景。以下是解决方案: 1. **检查服务名称冲突** 在节点代码中搜索所有 `advertiseService()` 调用,确保服务名称唯一: ```cpp // 错误示例:重复注册同名服务 ros::ServiceServer service1 = nh.advertiseService("/set_parameters", callback1); ros::ServiceServer service2 = nh.advertiseService("/set_parameters", callback2); // 名称冲突! // 正确做法:使用唯一名称 ros::ServiceServer service1 = nh.advertiseService("/config/set_parameters", callback1); ros::ServiceServer service2 = nh.advertiseService("/calib/set_parameters", callback2); ``` 2. **动态参数服务器冲突处理** 使用 `dynamic_reconfigure` 时,合并参数配置到单个服务器: ```python from dynamic_reconfigure.server import Server from my_pkg.cfg import Config1, Config2 # 合并后的配置文件 # 统一参数服务器 server = Server(Config1, callback) # 替代多个独立服务器[^2] ``` 3. **命名空间隔离** 为不同功能模块分配独立命名空间: ```xml <!-- launch 文件中隔离节点 --> <group ns="kinect2_calib"> <node name="calib_node" pkg="my_pkg" type="calib_node"/> </group> <group ns="kinect2_depth"> <node name="depth_node" pkg="my_pkg" type="depth_node"/> </group> ``` #### 二、解决 CMake 配置不完整问题 针对 Gazebo 包弃用和依赖缺失问题: 1. **修复 Gazebo 依赖(ROS Noetic)** ```bash sudo apt install ros-noetic-gazebo-ros-pkgs \ ros-noetic-gazebo-ros-control \ ros-noetic-gazebo-plugins ``` 2. **更新 `package.xml`** ```xml <depend>gazebo_ros</depend> <depend>gazebo_plugins</depend> <depend>gazebo_ros_control</depend> <depend>serial</depend> <!-- 解决引用[4]的OpenCL类问题 --> ``` 3. **修正 `CMakeLists.txt`** ```cmake find_package(catkin REQUIRED COMPONENTS gazebo_ros gazebo_ros_control gazebo_plugins OpenCL # 解决引用[4]的OpenCL缺失 ) ``` 4. **完整编译流程** ```bash cd ~/catkin_ws rm -rf build devel # 清理旧编译 rosdep install --from-paths src --ignore-src -y # 安装缺失依赖[^3] catkin_make -DCMAKE_BUILD_TYPE=Release source devel/setup.bash ``` #### 三、虚拟机图形渲染问题处理 针对引用[4]的 OpenCL 错误和虚拟机图形问题: ```bash # 安装 OpenCL(版本≥2) sudo apt install ocl-icd-opencl-dev beignet # 虚拟机设置: # 1. 启用3D加速(VMware:虚拟机设置 > 显示器 > 加速3D图形) # 2. 使用软件渲染备用方案: export LIBGL_ALWAYS_SOFTWARE=1 ``` > **关键验证**: > - 检查服务唯一性:`rosservice list | grep set_parameters` > - 验证 OpenCL:`clinfo | grep "Version"` 应显示 ≥2.0[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值