编辑推荐: |
本文于exbot.net,介绍了如何使用Scratch2和ROS进行机器人编程的学习过程和控制机器人的示例演示。
|
|
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/
scratch2 jderobot/'
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") |
|