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

标签: ROS scratch python 人工智能 机器人
1508人阅读 评论(0) 收藏 举报
分类:

使用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")


----


查看评论

exeLock技术完全分析

     真辛苦啊!这是我想说的第一句话。     有时痛苦得都不想做下去了,但我始终相信我可以做出来,就坚持下来了。要命的是,我的键盘和鼠标都不太灵活了,更要命的是,我连买一只新鼠标的钱都拿不出来!...
  • bodies
  • bodies
  • 2001-12-12 09:28:00
  • 917

ROS service入门到应用

ROS Service 入门到应用使用ros有一段时间了,但是一般topic类型的通信方式使用的最多,很少使用service,所以对service也就是简单的了解,并没有真正的使用过,最近要用到ser...
  • Start_From_Scratch
  • Start_From_Scratch
  • 2017-03-06 00:38:05
  • 1068

ROS学习——常用图形化工具

(1) rosrun rqt_topic rqt_topic(2) rosrun rqt_publisher rqt_publisher(3) rosrun rqt_plot rqt_plot
  • zhousonglin20112011
  • zhousonglin20112011
  • 2018-03-18 17:41:00
  • 25

ROSbridge:为你的机器人构建WEB图形用户界面

安装rosbridge程序包sudo apt-get update sudo apt-get install ros-indigo-rosbridge-suite ros-indigo-robot-p...
  • qq_16397695
  • qq_16397695
  • 2017-09-21 15:03:31
  • 215

ROS(indigo) 用于机器人控制的图形化编程工具--code_it robot_blockly

0 简介: 编程语言有汇编,高级语言,解释语言等,现在图形化编程也越来越流行。图形化编程简单易学。8年前,微软推出了VPL用于机器人程序设计,如Python和JavaScript都可以用图形化框...
  • roslei
  • roslei
  • 2016-12-04 10:30:24
  • 2304

如何用Qt对ROS项目进行调试及创建GUI界面

一、前言本文详细介绍了利用CMakeLists.txt文件把ROS项目导入到QtCreator进行代码编写和调试的过程,文末还介绍了ROS中使用Qt界面的方法 这种导入ROS项目到Qt的方法也适...
  • u013453604
  • u013453604
  • 2016-08-09 23:48:26
  • 13821

ROS机器人编程新书推荐(附免费下载)

来源网站一本新的ROS书籍:“ROS机器人编程,由TurtleBot3开发人员编写”。 现在,这本书已经出版了英文和中文版本。 你可以下载这本书的pdf。本书的作者想要感谢Morgan、Tully、O...
  • ZhangRelay
  • ZhangRelay
  • 2018-02-09 23:10:45
  • 1845

复习在ROS机器人系统中打开摄像头,显示图像

在打开摄像头时候出现的错误:ERROR cannot launch node of type[uvc_cam/uvc_cam_node]............ 只要是没有装ROS的摄像头的驱动。 ...
  • C_ROS
  • C_ROS
  • 2015-11-17 13:58:56
  • 2300

ROS探索总结(四)(五)(六)——简单的机器人仿真 创建简单的机器人模型smartcar 使用smartcar进行仿真

ROS探索总结(四)——简单的机器人仿真 前边我们已经介绍了ROS的基本情况,以及新手入门ROS的初级教程,现在就要真正的使用ROS进入机器人世界了。接下来我们涉及到...
  • GarfieldEr007
  • GarfieldEr007
  • 2016-04-22 14:24:07
  • 3694

致家长--为什么选择Scratch

有兴趣的同学也可以加入此群大家共同探讨小孩的未来:214084813对于儿童编程对我来说是情怀也是真有必要,下文的作者也表达了我相同的看法,希望家长能有耐心的看完。 “从小就编程”有可能不只是名人传...
  • zxm317122667
  • zxm317122667
  • 2016-11-30 16:34:41
  • 2937
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 100万+
    积分: 1万+
    排名: 1407
    博客专栏
    最新评论