首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Scratch2和ROS进行机器人图形化编程学习

使用Scratch2和ROS进行机器人图形化编程学习

作者头像
zhangrelay
发布2019-01-31 15:57:28
8890
发布2019-01-31 15:57:28
举报

使用Scratch2和ROS进行机器人编程学习(适用于中小学机器人编程Scratch和ROS)

Scratch是一款由麻省理工学院(MIT)设计开发的少儿编程工具Python是近年来非常流行的机器人和人工智能编程语言ROS是机器人操作系统

参考JdeRobot的一篇详细介绍,就可以实现上述的功能,需要安装Scratch2、ROS Kinetic、Gazebo 7、JdeRobot、Python2.7等。

通过将Scratch2图形化编程语言转为Python,然后通过ROS消息机制控制Gazebo或实际机器人。

上海久牵志愿者服务社2017中国困境儿童关注日

~~信息化智能化时代下平等受教育的权利~~

1 先看如下一个简单的示例

1.1 新建hiros.bz2,如下:

1.2 通过下面命令将其转为Python:

$ python scratch2python.py hiros.sb2
Stringify:
when @greenFlag clicked
repeat 10
    say 'Hello,ROS Kinetic!'
end
[WARN] Block <when @greenFlag clicked> not included yet

-------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import config
import sys
import comm
import os
import yaml

from drone import Drone
from robot import Robot

def execute(robot):
    try:
        
        for i in range(10):
            print('Hello,ROS Kinetic!')
        
    except KeyboardInterrupt:
        raise

if __name__ == '__main__':
    if len(sys.argv) == 2:
        path = os.getcwd()
        open_path = path[:path.rfind('src')] + 'cfg/'
        filename = sys.argv[1]

    else:
        sys.exit("ERROR: Example:python my_generated_script.py cfgfile.yml")

    # loading the ICE and ROS parameters
    cfg = config.load(open_path + filename)
    stream = open(open_path + filename, "r")
    yml_file = yaml.load(stream)

    for section in yml_file:
        if section == 'drone':
            #starting comm
            jdrc = comm.init(cfg,'drone')

            # creating the object
            robot = Drone(jdrc)

            break
        elif section == 'robot':
            #starting comm
            jdrc = comm.init(cfg,'robot')

            # creating the object
            robot = Robot(jdrc)

            break
    # executing the scratch program
    execute(robot)


-------------------

2 控制机器人示例

是不是比较有趣,在不需购买任何设备的情况下,就可以用Scratch2进行ROS机器人编程。小学用Scratch2学习简单编程,中学用Python学习简单编程,大学用Python和C++学习复杂机器人编程,无缝衔接。

3 scratch2python.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = "Raul Perula-Martinez"
__copyright__ = "JdeRobot project"
__credits__ = ["Raul Perula-Martinez"]
__license__ = "GPL v3"
__version__ = "0.0.0"
__maintainer__ = "Raul Perula-Martinez"
__email__ = "raules@gmail.com"
__status__ = "Development"

import kurt
import os
import sys

from difflib import SequenceMatcher
from parse import parse, compile
from termcolor import cprint


GENERAL = [
    ['end', ''],
    ['forever', 'while True:'],
    ['if {} then', 'if %s:'],
    ['else', 'else:'],
    ['repeat {}', 'for i in range(%s):'],
    ['say {}', 'print(%s)'],
    ['set {} to {}', '%s = %s'],
    ['wait {} secs', 'time.sleep(%s)'],
]

ROBOTICS = [
    ['move robot {}', 'robot.move("%s")'],
    ['move drone {}', 'robot.move("%s")'],
    ['move robot {} speed {}', 'robot.move("%s", %s)'],
    ['stop robot-drone', 'robot.stop()'],
    ['turn robot-drone {}', 'robot.turn("%s")'],
    ['turn robot {} speed {}', 'robot.turn("%s", %s)'],
    ['take off drone', 'robot.take_off()'],
    ['land drone', 'robot.land()'],
    ['frontal laser distance', 'robot.get_laser_distance()'],
]

def is_conditional(sentence):
    """
    Returns if a sentence is conditional or not.

    @param sentence: The sentence to check.
    @return: True if it has a conditional, False otherwise.
    """

    if "if" in sentence:
        return True

    return False


def similar(a, b):
    """
    Returns the ratio value comparing two sentences.

    @param a: First sentence.
    @param b: Second sentence.
    @return: The ratio of the similarity.
    """

    return SequenceMatcher(None, a, b).ratio()


def sentence_mapping(sentence, threshold=None):
    """
    Maps a sentence and returns the original and the mapped.

    @param sentence: The sentence to map.
    @return: The original sentence and the mapped sentence.
    """

    found = False
    options = []
    original = None
    translation = None

    # first look for general blocks
    for elem in GENERAL:
        if elem[0][:3] == sentence.replace('    ', '')[:3]:
            options.append(elem)
            found = True

    # then look for robotics blocks
    for elem in ROBOTICS:
        if elem[0][:3] == sentence.replace('    ', '').replace('(', '')[:3]:
            options.append(elem)
            found = True
    if found:
        # select the option that better fits
        l = [(m[0], m[1], similar(sentence, m[0])) for m in options]
        original, translation, score = max(l, key=lambda item: item[2])
        if threshold and score < threshold:
            return None, None

        # extract arguments
        p = compile(original)
        args = p.parse(sentence.replace('    ', ''))
        if args:
            args_aux = list(args)

            # look for more blocks
            for idx in range(len(args_aux)):
                new_ori, new_trans = sentence_mapping(args_aux[idx]) #sentence_mapping(args_aux[idx],0.8) --old
                if new_trans != None:
                    args_aux[idx] = args_aux[idx].replace(new_ori, new_trans) #replace(args_aux[idx], new_trans)
            translation = translation % tuple(args_aux)
    return original, translation


if __name__ == "__main__":
    # get current working directory
    path = os.getcwd()
    open_path = path[:path.rfind('scripts')] + 'data/'
    save_path = path[:path.rfind('scripts')] + 'src/scratch2jderobot/'

    if len(sys.argv) == 2:
        # template creation

        template = "\
#!/usr/bin/env python\n\
# -*- coding: utf-8 -*-\n\n\
import time\n\
import config\n\
import sys\n\
import comm\n\
import os\n\
import yaml\n\n\
from drone import Drone\n\
from robot import Robot\n\n\
def execute(robot):\n\
\ttry:\n\
\t%s\
except KeyboardInterrupt:\n\
\t\traise\n\n\
if __name__ == '__main__':\n\
\tif len(sys.argv) == 2:\n\
\t\tpath = os.getcwd()\n\
\t\topen_path = path[:path.rfind('src')] + 'cfg/'\n\
\t\tfilename = sys.argv[1]\n\n\
\telse:\n\
\t\tsys.exit(\"ERROR: Example:python my_generated_script.py cfgfile.yml\")\n\n\
\t# loading the ICE and ROS parameters\n\
\tcfg = config.load(open_path + filename)\n\
\tstream = open(open_path + filename, \"r\")\n\
\tyml_file = yaml.load(stream)\n\n\
\tfor section in yml_file:\n\
\t\tif section == 'drone':\n\
\t\t\t#starting comm\n\
\t\t\tjdrc = comm.init(cfg,'drone')\n\n\
\t\t\t# creating the object\n\
\t\t\trobot = Drone(jdrc)\n\n\
\t\t\tbreak\n\
\t\telif section == 'robot':\n\
\t\t\t#starting comm\n\
\t\t\tjdrc = comm.init(cfg,'robot')\n\n\
\t\t\t# creating the object\n\
\t\t\trobot = Robot(jdrc)\n\n\
\t\t\tbreak\n\
\t# executing the scratch program\n\
\texecute(robot)\n\n\
"

        # load the scratch project
        p = kurt.Project.load(open_path + sys.argv[1])

        # show the blocks included
        for scriptable in p.sprites + [p.stage]:
            for script in scriptable.scripts:
                # exclude definition scripts
                if "define" not in script.blocks[0].stringify():
                    s = script
        print("Stringify:")
        sentences = []
        for b in s.blocks:
            print(b.stringify())
            sentences += b.stringify().split('\n')
        tab_seq = "\t"
        python_program = ""

        for s in sentences:
            # count number of tabs
            num_tabs = s.replace('    ', tab_seq).count(tab_seq)
            python_program += tab_seq * (num_tabs + 1)

            # pre-processing if there is a condition (operators and types)
            if is_conditional(s):
                s = s.replace("'", "").replace("=", "==")

            # mapping
            original, translation = sentence_mapping(s)

            # set the code
            if translation != None:
                python_program += translation
            else:
                cprint("[WARN] Block <%s> not included yet" % s, 'yellow')
            python_program += "\n" + tab_seq

        # join the template with the code and replace the tabs
        file_text = template % python_program
        file_text = file_text.replace(tab_seq, ' ' * 4)

        print("\n-------------------")
        cprint(file_text, 'green')
        print("-------------------\n")

        # save the code in a python file with the same name as sb2 file
        file_name = sys.argv[1].replace('.sb2','.py')
        f = open(save_path + file_name, "w")
        f.write(file_text)
        f.close()

    else:
        print(
            "ERROR: Number of parameters incorrect. Example:\n\tpython scratch2python.py hello_world.sb2")

----

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年12月20日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用Scratch2和ROS进行机器人编程学习(适用于中小学机器人编程Scratch和ROS)
    • 1 先看如下一个简单的示例
      • 1.1 新建hiros.bz2,如下:
      • 1.2 通过下面命令将其转为Python:
    • 2 控制机器人示例
      • 3 scratch2python.py
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档