KBEngine学习笔记 - Entity_defs和EntityCall

本文档详细介绍了KBEngine中entity_defs文件的结构和使用,特别是BaseMethods部分。EntityCall是脚本层与实体远程交互的关键,必须在def文件中声明相应方法才能调用。文中通过实例解释了如何在不同部分(如BaseMethods、ClientMethods、CellMethods)声明方法,以确保跨进程交互的正确性,并强调了所有entityCall调用的方法都需要在def文件中定义。

在使用KB引擎开发中,因工作问题放了一段时间,彻底不记得entity_defs 文件中需要怎么加,他们又是怎么交互的,今天开个文档记录一下。

一般分为Properties(属性)部分、BaseMethods(基础)、CellMethods(空间)、ClientMethods(客户端)这4个部分(如下),Properties这个不是今天的重点,后面有机会单独写一个属性部分文章。

		<Properties>
		</Properties>
		<BaseMethods>
		</BaseMethods>
		<ClientMethods>
		</ClientMethods>
		<CellMethods>
		</CellMethods>

首先我们讲一下BaseMethods里需要加哪些方法。这个明白了其他的就明白了。

我们知道EntityCall是脚本层与实体远程交互的常规手段。(其他参考:allClients、otherClients、clientEntity)。

EntityCall对象在C++底层实现非常简单,它只包含了实体的ID、目的地的地址、实体类型、EntityCall类型。当用户请求一次远程交互时,底层首先能够通过实体类型找到实体定义的描述,
通过实体定义的描述对用户输入的数据进行检查,如果检查合法那么底层将数据打包并发往目的地,目的地进程根据协议进行解包最终调用到脚本层。

注意: EntityCall只能调用其对应def文件中声明过的方法,不能访问实体的属性以及其他任何信息。

一个实体最多可以包含三个部分:
client: 当实体包括客户端部分时(通常为玩家),在服务端可以访问实体的client(EntityCall)属性。
base:当实体的一部分创建在Baseapp时,在非当前Baseapp中可以访问实体的base(EntityCall)属性。
cell:当实体的一部分创建在Cellapp时,在非当前Cellapp中可以访问实体的cell(EntityCall)属性。

举例说明,假设玩家登录调用了
KBEngine.globalData[“Halls”].enterHalls(self)
表示玩家首先登录了大厅,代码如下:

		#进入了大厅
		def enterHalls(self, entityCall):
			"""
			defined method.
			请求进入某个Room中 
			"""
			self.entities[entityCall.id] = entityCall
			entityCall.SendHallData(self.typeEntitiesNum)

如果我们没有在Halls.def中定义

<BaseMethods>
    <enterHalls>
      <Arg>		ENTITYCALL		</Arg>
    </enterHalls>
</BaseMethods>

那么这个函数会报错(当然你开一个base进程是不会的),我们只要记得KBEngine.globalData[“Halls”] 存在于唯一的base进程,其他进程的都是entityCall。所以其他的base进程也要调用,这种就需要你在BaseMethods里声明,相当于跨进程了。

那么我们继续思考下,我们上面的代码中有一行代码
entityCall.SendHallData(self.typeEntitiesNum)
这个假设是负责玩家登录后把大厅登录的总人数回传给Acount,那么这个SendHallData需不需要再def中定义?答案是肯定的,玩家的对象可能也是一个entityCall ,是他调用了SendHallData
所以我们需要在Account.def中定义

<SendHallData>
      <Arg>            ROOM_DATA_NUMBER            </Arg>
</SendHallData>

所以只要记住只要是entityCall调用就必须声明。
CellMethods和ClientMethods也是同理的。你如果有多个baseApp,那么你的Acount必然存在多个进程中,那么除了真实的Entity,其他也都是entityCall,所以如果把上面的人数要同步到玩家客户端,那么也需要在def中声明,只不过这个要放到ClientMethods里才行,为了和上面的SendHallData区分我加了一个Int32参数,看起来不混淆。

#进入大厅后刷新到客户端的
	def SendHallData(self, hallData):
		INFO_MSG("account[%i],大厅数据发给客户端!!![%i]. entityCall:%s" % (self.id,len(hallData), self.client))
		self.client.SendHallData(len(hallData), hallData)
  <ClientMethods>
    <SendHallData>
      <Arg>            INT32            </Arg>
      <Arg>            ROOM_DATA_NUMBER            </Arg>
    </SendHallData>
  </<ClientMethods>>

至于CellMethods当然是在CellApp进程上的,我们依此类推。

<think>我们遇到的问题是在使用`spawn_entity.py`时出现错误:`error: the following arguments are required: -entity`。 根据错误信息,很明显是因为没有提供`-entity`参数。但是,根据引用[2]的描述,`spawn_entity.py`这个文件在启动时是需要传递`-entity`参数的。 分析错误: 错误提示告诉我们,缺少必需的参数`-entity`。这意味着在调用`spawn_entity.py`脚本时,没有指定`-entity`参数。 根据引用[2]中的描述,他们是这样启动的: 使用了`spawn_entity.py`,并且指定了`-entity`参数(通过`robot_name`变量传递,默认为`turtlebot3_waffle`)。 因此,我们需要检查调用`spawn_entity.py`的命令行,确保包含了`-entity`参数。 例如,一个典型的调用应该是这样的: `/opt/ros/humble/lib/gazebo_ros/spawn_entity.py -entity my_robot -topic robot_description ...` 但是,如果我们在调用时没有提供`-entity`参数,就会出现上述错误。 解决方案: 在调用`spawn_entity.py`时,必须指定`-entity`参数,并为它赋予一个字符串值(即给要生成的实体起一个名字)。 例如: `ros2 run gazebo_ros spawn_entity.py -entity my_robot -topic robot_description -x 0 -y 0 -z 0.5` 注意:`-entity`参数后面必须紧跟一个字符串(不能为空,且不能是其他参数)。 如果是在launch文件中使用,确保在`Node`或`ExecuteProcess`中正确传递了`-entity`参数。 例如,在launch文件中可能这样写(使用`launch_ros.actions.Node`): ```python spawn_entity = Node( package='gazebo_ros', executable='spawn_entity.py', arguments=[ '-entity', 'my_robot', '-topic', 'robot_description', '-x', '0.0', '-y', '0.0', '-z', '0.5' ], output='screen', ) ``` 或者,如果使用`ExecuteProcess`: ```python spawn_entity = ExecuteProcess( cmd=['ros2', 'run', 'gazebo_ros', 'spawn_entity.py', '-entity', 'my_robot', '-topic', 'robot_description', '-x', '0.0', '-y', '0.0', '-z', '0.5'], output='screen' ) ``` 请检查你的调用命令或launch文件,确保包含了`-entity`参数。 另外,根据引用[3],我们看到在launch文件中使用了`launch``launch_ros`模块,以及参数传递。这也提醒我们在launch文件中正确设置参数的重要性。 引用[4]展示了如何使用服务调用来生成实体,这也是一种替代方法,但我们现在的问题是关于命令行参数缺失。 总结:缺少`-entity`参数,必须添加。 相关问题: 1. 在ROS 2的launch文件中如何正确传递参数给节点? 2. 除了使用`spawn_entity.py`,还有哪些方法可以在Gazebo中生成机器人模型? 3. 如何通过ROS 2服务调用的方式在Gazebo中生成实体? </think>### 解决 `spawn_entity.py error: the following arguments are required: -entity` 问题 #### 问题分析 当使用 Gazebo ROS 的 `spawn_entity.py` 脚本时出现 `required: -entity` 错误,表明调用时缺少必需的 `-entity` 参数。根据引用[1][2][4]的信息,该参数用于指定要生成的机器人实体名称,是脚本执行的必需参数。 #### 解决方案 ##### 1. 确保命令包含 `-entity` 参数 ```bash # 正确格式示例 ros2 run gazebo_ros spawn_entity.py \ -entity my_robot \ # 必须指定实体名称 -topic robot_description \ -x 4.0 -y 3.0 -z 2.0 ``` ##### 2. 检查 Launch 文件配置(引用[2][3]) 在 launch 文件中确保正确传递参数: ```python # 示例代码(参考引用[3]) from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='gazebo_ros', executable='spawn_entity.py', arguments=[ '-entity', 'turtlebot3', # 必须指定实体名 '-topic', 'robot_description', '-x', '0.0', '-y', '0.0', '-z', '0.1' ] ) ]) ``` ##### 3. 验证参数传递顺序 确保 `-entity` 是第一个位置参数: ```diff # 错误顺序(导致参数解析失败) spawn_entity.py -x 0 -y 0 -entity robot # 正确顺序(引用[4]) spawn_entity.py -entity robot -x 0 -y 0 ``` #### 常见错误场景 1. **Launch 文件遗漏参数**(引用[2]): ```python # 错误:缺少 -entity 参数 arguments=['-topic', 'robot_description', '-x', '0.0'] ``` 2. **命令行参数缺失**: ```bash # 错误:缺少 -entity ros2 run gazebo_ros spawn_entity.py -topic robot_description ``` #### 完整调试流程 ```mermaid graph TD A[出现 -entity 缺失错误] --> B{检查命令行/launch文件} B -->|命令行调用| C[添加 -entity <名称> 参数] B -->|launch文件调用| D[检查 Node arguments 数组] D --> E[确认包含 '-entity', '名称' 元素] E --> F[验证参数顺序] F --> G[重新运行测试] ``` #### 替代解决方案(引用[4]) 如果仍存在问题,可改用 ROS 服务调用: ```bash ros2 service call /spawn_entity gazebo_msgs/srv/SpawnEntity ' { name: "my_robot", # 相当于 -entity 参数 xml: "<robot name='my_robot'>...</robot>" }' ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Thinbug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值