通过云技能控制ROS机器人


(一方风景) #1

大家好我是风景,出于爱好,我将云技能跟ROS框架结合起来,搞了一个控制机器人导航的云技能,由于本人不具备前后端经验,JS也是临时学习,所以一些细节可能讲解不到位,还望各位多多指教。


前期准备:

  1. 云服务器一台

  2. Rokid云技能

  3. 本地PC安装ROS系统(本人为Ubuntu16.04 + Kinetic)


正文开始

创建技能的步骤不在此赘述,在技能中选用Rokid JS Engine作为后端服务,当然大神们也可以直接用自己搭的服务器来搞。

我是通过向服务器get的方式来传输关键字的,在RFS中,设置报文如下:

var options1 = {
    method: 'GET',
    url: 'http://YOUR_IP:PORT/?YOUR_ARG=WHAT',
    headers:
    {
        'User-Agent': 'request'
    }
};

然后在主函数中,设置一个跟意图定义部分设置的intents相对应的函数:

'nav1':function() {
    try{
        Rokid.request(options1, function (error, response, body) {
            if (error) {
                this.emit('ROKID.INTENT.EXIT');
            }
        });
        this.emit(':done');
    } catch (e) {
        this.emit(':error', e);
    }
}

接下来是云服务器部分:

采用了比较简单的Flask作为服务端,其介绍文档比较丰富,在此不做赘述。

http://flask.pocoo.org/docs/1.0/

在云服务器接收到GET后,进入一个决策树,可以选择对机器人发送不同的指令, 本文中以ROS中的定点Navigation为例。

云服务器和PC端的通讯则通过简单的Socket通讯完成,由于代码过长,只贴核心实现:

@app.route('/', methods=['GET'])
def YOUR_FUNC():
    global server
    arg = int(request.args['YOUR_ARG'])
    try:
        server.sendToAll(arg.encode('utf-8'))
    except Exception as e:
        print(e)
    return 'Hello World!'

接下来介绍本地PC部分的配置:

PC端相较于云服务器和技能端,配置相对来说简单。同样限于篇幅,只贴核心实现:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('YOUR_IP', YOUR_PORT))

try:
    global move_base

    rospy.init_node('ASR_control', anonymous=True)
    rate = rospy.Rate(1)

    marker = list()
    find_words = list()
    find_words.append('Position 1')

    marker.append(Pose(Point(0.499, 0.975, 0.0), \
        Quaternion(0.0, 0.0, 0.008, 1.000)))

    move_base = actionlib.SimpleActionClient("move_base", MoveBaseAction)

    move_base.wait_for_server(rospy.Duration(60))

    while True:
        buffer = s.recv(1024)
        if (len(buffer) <= 0):
            break
        if (buffer == YOUR_ARG):
            goal = MoveBaseGoal()
            goal.target_pose.header.frame_id = 'map'
            goal.target_pose.header.stamp = rospy.Time.now()
            goal.target_pose.pose = marker[0]
            move(goal)
        print buffer

except rospy.ROSInterruptException:
    rospy.loginfo("InterruptException.")

大功告成~

最后贴两张实时图片以供参考