Ros2中动作通信的goal_handle类型在不同回调函数中的区别

在进行Ros2学习和进行项目的开发途中,准确来说实在动作通信项目的实战中,我给出了以下示例的ActionServer端初始化,并且使用goal_handle进行下一步操作。

        self.server = ActionServer(
            self,
            Nav,
            "nav",
            execute_callback=self.execute,
            goal_callback=self.handle_goal,
            cancel_callback=self.handle_cancel,
            handle_accepted_callback=self.handle_accepted,
        )

以下是我的Nav.action,简而言之,是我的动作接口,当我在使用goal_handle的goal_x = goal_handle.request.goal_x方法来获取客户端传来的数据时,竟然报错了,而且错误是Nav_Goal没有request这个方法,但是goal_handle明明是ServerGoalHandle类型,且是有request这个方法的,为什么会这样呢?

float32 goal_x
float32 goal_y
float32 goal_theta
---
float32 turtle_x
float32 turtle_y
float32 turtle_theta
---
float32 distance

在经过我查看源码后我发现,在default_goal_callback()函数中给出的是goal_request,在default_cancel_callback()函数中给出的是cancel_request,只有在执行函数过度的default_handle_accepted_callback()中才给出了goal_handle这一类型的指定,所以并不能直接认为这些函数给出的handle是相同的,换言之,将每个函数中的参数都写成goal_handle是不准确的,也不应该这么做。

def default_goal_callback(goal_request):
    """Accept all goals."""
    return GoalResponse.ACCEPT

def default_cancel_callback(cancel_request):
    """No cancellations."""
    return CancelResponse.REJECT

def default_handle_accepted_callback(goal_handle):
    """Execute the goal."""
    goal_handle.execute()

即以下写法不准确,不应全写成goal_handle

    def handle_goal(self, goal_handle):
        pass
    def handle_cancel(self, goal_handle):
        pass
    def handle_accepted(self, goal_handle):
        pass
    def execute(self, goal_handle):
        pass

经过查询和尝试得知:Nav_Goal是一个数据类,通常包含目标动作的请求数据。包含目标的具体字段 goal_x,goal_y,goal_theta等。在处理目标时,Nav_Goal是接收和发送的实际数据。于是通过查看源码发现handle有一个take_data()方法,试了发现Nav_Goal没有这个方法,于是就直接访问其内部的数据,发现可行。

    def handle_goal(self, goal_handle):
        self.get_logger().info(
            f"请求坐标: ({goal_handle.goal_x:.2f}, {goal_handle.goal_y:.2f}), 航向: {goal_handle.goal_theta:.2f}"
        )
        if (
            goal_handle.goal_x < 0
            or goal_handle.goal_x > 11.1
            or goal_handle.goal_y < 0
            or goal_handle.goal_y > 11.1
        ):
            return GoalResponse.REJECT
        return GoalResponse.ACCEPT

而下方的执行部分,不出所料地肯定是ServerGoalHandle类型,于是继续是用老方法就行了

        goal_x = goal_handle.request.goal_x
        goal_y = goal_handle.request.goal_y

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值