报错日志1:terminate called after throwing an instance of ‘ros::TimeNotInitializedException‘——ROS项目报错

本文记录了一次在ROS项目中遇到的时间未初始化异常问题及其解决过程。作者在修改代码时无意间注释掉了NodeHandle的创建语句,导致使用ROS时间相关的功能时报错。通过重新启用NodeHandle创建代码解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今日报错(渔舟唱晚BGM起):

terminate called after throwing an instance of 'ros::TimeNotInitializedException'

  what():  Cannot use ros::Time::now() before the first NodeHandle has been 
  created or ros::start() has been called. 
 
  If this is a standalone app or test that just uses ros::Time and does not 
  communicate over ROS, you may also call ros::Time::init()

  已放弃 (核心已转储)

 开场白:大家好啊,这篇博文是鄙人新开的一个专题《报错日志》的第一期。开这个专题的主要原因是心血来潮,想和大家以一种诙(shen)谐(jing)有(bing)趣(fa)的笔调分享一下我在编程过程中,遇到的各式各样的报错(唯一的共同点就是都令人心脏骤停,血压飙升)。希望大家在看的开心的同时,也能吸取鄙人的教训,可以规避我的错误,开开心心地编程(雪豹:然而历史中唯一可以学到的,就是人类永远不会吸取历史的教训~~假面DJ:雪豹闭嘴,不要坏了我的好事)。

Ps:想要直接看解决方法的朋友急急国王可以快进(Made in heaven)到文章的末尾进行查看。

事不宜迟,这里是Kamen Black君,就让我们开始今天的博文吧:

正文部分:

5bc45280be5946aabe35b2a0f1c252dc.png

print("祝大家每天快乐,love and peace!")

事情的起因:

月光披萨披撒在自习室的地板上,看着时钟逐渐向23:30靠拢,我知道,留给我的时间不多了。在查看了一遍项目之后,像往常一样随便地修整一下,填个注释啥的之后,我就停止了风扇的呜咽,从此绝尘而去,不再回头(混蛋,回宿舍有必要这么写得这么凄凉吗)。

第二天,阳光明媚,一如往常,我,像往常一样喝一口凉白开,像往常一样优雅地坐下,像往常一样打开了Ubuntu,像往常一样地打开vscode,像往常一样打开我的ros项目,像往常一样打开一个节点的c++文件,之后像往常一样地打开终端,像往常一样运行着rosrun的命令。

然后不往常的事情的发生了,要知道在过去的5天零9小时23分钟零9秒(分秒都是瞎编的)没有任何异常发生,但是那一刻它还是发生了。

世上最大极恶事件、超高校级绝望、连最凶恶的罪犯看了都直摇头的那件事发生了——报错

那可恶的证据就在下面,大家请看:

94a53a611f25464da90232bd8120cfbb.png

已放弃三个字血淋淋地像一支利箭插在了我的心里 。

我又重新试了一遍又一遍,每一次却都是白花花的文字,在我眼里却像是红极了的魔鬼的文字。这些无情的咒语,仿佛在展示世界的无情,又像是在斥责我的罪状,仿佛在告诉我这一切都是徒劳的,这么多天的顺利运行,现在都在我的眼前分崩离析,一切都在离我远去。往日的荣耀都已不在,往日的欢乐都已逝去,往日的美好再难重现,世界啊,崩塌吧。。。。。。

 2239a9d7b72540cd925feed5097c7d44.jpeg

嗯哼哼哼~~~停停停,发病发到这就该结束了(主要是已经发泄爽了),又不是荷马史诗续集,或者希腊神话再版。

我们是社会主义国家,生在红旗下,长在春风里,我们要坚信唯物主义,我们要相信科学!。其实问题很简单,就是一天在运行ROS项目中一个节点的过程中,发现了运行错误的问题。

下面是我拯救程序(收拾烂摊子)的过程:

刚开始我并没有看懂报错到底是啥意思,只是看到我最熟悉的中文——已放弃(核心已转储),本着就近原则(才不是因为懒,而没去看英文),因而小白朴素的我就以为是文件的位置配置出现了问题,所以干脆直接将原来的文件包直接删除,之后将提前复制好的程序代码粘贴到新的C++文件当中。之后,打开终端,熟练地输入了rosrun的命令,然后就顺利地。。。。。。爆出了和之前一样的错误。唯有泪千行啊。

既然已经知道不是文件位置配置上的错误之后,我又想到了是不是VScode的问题,毕竟我是通过VScode进行节点编译的,这里不得不感叹一声VScode真好用啊。(VScode快打钱)查看了半天VScode的插件以及相关的配置,我也没发现具体的问题。之后,我干脆一不做,二不休,直接将VScode一纸休书休回了娘家,换了个年轻的(其实就是卸载再重装:D),再按原本的配置将新的VScode重新调教修整了一遍。一切都收拾好之后,我再次打开终端,满怀希望地输入rosrun的命令,然后就顺利地。。。。。。再次报错了。算了都已经习惯了~~

苏格兰小说家阿瑟▪柯南▪道尔曾经借他笔下的小说角色——夏洛克▪福尔摩斯说过一句话“Eliminate all other factors, and the one which remains must be the truth.”(出自《四签名》第一章),用中文说就是“排除了所有的可能性之后,剩下的那个一定就是真相”,无论它有多么难以置信。那么真相只有一个(新机子挖一自摸一肚子)(bgm起)——代码出现了问题。

大家还记得,我之前在事情的起因部分说过的一句话吗,没错就是“像往常一样随便地修整一下,填个注释啥的”。这就是原罪。

首先,我观察起了报错的英文部分(时不容我懒),然后我注意到了这句话:

what():  Cannot use ros::Time::now()

what指向的一定是出错的问题所在,然后我看向了这句话冒号后面的部分“cannot use ros::Time::now”。这时我开始疑惑,我好像并没有在代码中用到ros头文件库中的Time函数库啊,怎么会出现ros::Time的报错了,唯一与时间Time扯上关系的只有一句:

ros::Rate loop_rate(0.5);

。。。。。。

突然,我发现了问题所在 ,在这句代码的上方有一句被我注释掉的代码:

ros::NodeHandle nh;

前一天晚上,因为自习室快要关门了,所以走得很匆忙,不知怎么(就是脑子抽抽了) ,我看代码中好像没有用得到NodeHandle的地方,就将它注释掉了。这时不脑子抽抽冷静的我,已经大概能够确定这就是问题所在了。此时我又注意到了what(): Cannot use ros::Time::now()的后半句话:

before the first NodeHandle has been created or ros::start() has been called

NodeHandle字眼的出现,让一切都水落石出。将注释取消掉之后,重新编译之后,打开终端,第三次运行rosrun的指令,这次终于顺利地。。。。。。运行成功了。(ohhhhhhh~~) 

原来,Rate函数只有在生成NodeHandle对象之后,才能被顺利调用。只有在生成NodeHandle对象之后,时间函数才会初始化,才能应用相关的函数。而“已放弃(核心已转储)”的意思是,终端放弃运行这个程序,将运行的处理器置空,留给其他待运行的程序。

曾经有一份完美的代码摆在我的眼前,我没有珍惜,等我失去的时候我才追悔莫及,人间最痛苦的事莫过于此。如果上天能再给我一个再来一次的机会,我会(推开代码)对曾经的自己说:你脑子是不是被驴踢了,自己写的代码都想不起来是怎么运行起来的。

在这里,我只能劝一句广大的同胞们:千万不要手欠,因为出来混总是要还的。在对你的代码下手之前,一定要三思而后行,其实对于任何事都是这样,一定要慎重,不然砍手是个迟早的事。

本次总结:

1、报错内容:

terminate called after throwing an instance of 'ros::TimeNotInitializedException'

  what():  Cannot use ros::Time::now() before the first NodeHandle has been 
  created or ros::start() has been called. 
 
  If this is a standalone app or test that just uses ros::Time and does not 
  communicate over ROS, you may also call ros::Time::init()

  已放弃 (核心已转储)

2、解决方法:

砍手(bushi) 对于ROS,在调用有关时间的函数之前,记得加上调用NodeHandle的代码,或者不要随便地将其注释掉。

结语:这个新专题如果大家喜欢的话,我会一直开展下去,和大家多分享一下我自己的报错吃瘪历程,也希望在这个过程中也能够帮助到一些和我同样有此类报错的小伙伴。

这个专题的博文会充斥比较多的个人经历、心理活动与夸张描述,一些朋友看了可能会觉得比较水(虽然我之前的博文也都挺水的)。

但是我个人觉得萝卜青菜,各有所爱,每个人都有自己喜欢与不喜欢的东西,我个人就比较喜欢看既有趣有能学到东西的文章,所以我想向大家呈现的也是这样的文章。

希望大家能在遭受挫折,坚持不下去时,能翻翻自己的收藏夹(疯狂暗示),知道世界上还有这么一个沙雕的灵魂和你们同在,你们不是一个人在战斗,你不是一个人(你懂我的意思:D)!如果你是开开心心的时候看到我的博文,那就更要将这种心情保持下去,人总要保持乐观,才能迎接这世上的风风雨雨。

好了以上就是所有的内容,希望大家多多关注,点赞,收藏,这对我有很大的帮助。谢谢大家了!

e63444f11e4844da927650cfd1d40197.gif

好了,这里是Kamen Black君。祝国康家安,大家下次再见喽!!!溜溜球~~

 1fefa946a8b0470787d5934be8922a6b.gif

 

### Gazebo 中 `common::Exception` 的解决方案 当在运行 Gazebo 时遇到 `terminate called after throwing an instance of 'gazebo::common::Exception'` 错误时,这通常表明程序内部发生了未捕获的异常并终止了执行过程。以下是可能的原因以及对应的解决方法: #### 可能原因分析 1. **依赖库版本不匹配** 如果安装的不同版本之间的依赖关系存在冲突,则可能导致此类错误发生[^1]。 2. **模型文件损坏或配置错误** 使用的 SDF/URDF 文件可能存在语法错误或者路径指定有误,从而引发解析失败并抛出异常。 3. **插件加载失败** 自定义开发的插件如果未能成功编译链接到项目中,在尝试调用这些功能模块期间也会触发类似的崩溃现象。 4. **资源不足** 当系统内存或其他硬件资源不足以支持仿真环境正常运作的时候也可能造成此问题。 #### 解决方案 针对上述提到的各种可能性提供如下几种处理办法: - #### 验证软件兼容性 确认当前所使用的 ROS 版本与 Gazebo 版本之间保持一致性和稳定性非常重要。可以查阅官方文档来获取推荐搭配组合列表,并按照指导完成重新部署工作。 - #### 检查世界描述文件(SDF/URDF) 利用工具如 `gz sdf -c your_model.sdf` 来验证模型结构的有效性;另外还需要仔细核对所有外部引用(比如材质贴图、碰撞网格等)是否都指向实际存在的位置。 - #### 调试自定义插件 对于涉及第三方扩展部分的情况来说,应该先单独测试它们能否独立运行良好再集成进去整个框架里去。此外记得更新 CMakeLists.txt 和 package.xml 添加必要的依赖声明项以便正确构建目标二进制文件。 - #### 增加计算能力供给 尝试减少场景复杂度降低负载压力的同时也可以考虑升级物理机性能参数满足更高需求的应用场合下稳定表现的要求。 ```bash ulimit -n 65535 && gazebo --verbose world_file.world ``` 通过设置更大的文件句柄限制数配合开启详细的日志记录有助于定位具体哪个环节出了差错进而采取针对性措施加以修复。 ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kamen Black君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值