-
Notifications
You must be signed in to change notification settings - Fork 121
Notes on Using Blockly and its XML
We start with a blockly code snippet, that adds 1
and 2
and stores the result in x
. This is the result of the user's work with the browser-based front-end. Blockly handles all user actions.
Now the user clicks the show code
button. Blockly generates a XML representation of the graphical program. Our code snipped is represented as:
<block type="variables_set" id="b|fRG]X]?T;L=467q;dp" intask="true">
<mutation datatype="Number"/>
<field name="VAR">x</field>
<value name="VALUE">
<block type="math_arithmetic" id="3SQf4D5*xXxH%iAR:@;3" intask="true">
<field name="OP">ADD</field>
<value name="A">
<block type="math_number" id="kp`TFdz?,*z}t!dd_4!J" intask="true">
<field name="NUM">1</field>
</block>
</value>
<value name="B">
<block type="math_number" id="nL4n}Uj(OK%d14@UB:2V" intask="true">
<field name="NUM">2</field>
</block>
</value>
</block>
</value>
</block>
The XML is stored into a JSON object and send from the browser to a REST-endpoint of the server. From here everything is done with Java.
We transform the XML to an AST (abstract syntay tree), which is more adequate for further processing (i.e. code generation). This is done in two steps:
- XML to Jaxb generated beans (this is described below in detail, but it is a simple, fully automated job). The Jaxb framework generates everything needed.
-
Jaxb generated beans to AST. This is facilitated by the factory method
jaxbToAst
, which is availabe from all the classes, that can be part of the AST (these are always subclasses of classPhrase<V>
.
XML is not nice to process and furthermore XML should be validated w.r.t. a schema. The XML, which Blockly generates, matches the schema defined in OpenRobertaRobot/src/main/resources/blockly.xsd
. It is common to use the JAXB framework to process XML input and to use a JAXB tool to generate beans for the XML elements. This is done with maven at compile time. You'll find the generated classes in OpenRobertaRobot/target/generated-sources/jaxb/blockly/de/fhg/iais/roberta/blockly/generated
.
For unit test there exist a lot of helper classes (whose names follow the pattern *Helper*ForXmlTest
), which show, how the transformation with these generated classes is done programmatically. The basis of the transformation is class JaxbHelper
:
- it takes the
blockly.xsd
to generate two static objects: the schema objectblockSetSchema
and the jaxb context objectjaxbContext
. Note, that objects of classBlockSet
are the root of transformed XML. - method
BlockSet xml2BlockSet(String blocklyXml)
of classJaxbHelper
creates an unmarshaller (i.e. an transformer from XML to beans), sets the schema, starts the transformation and returns theBlockSet
object representing the transformed XML.
The bean returned is structurally equivalent to the XML. For instance, the XML element statement
contains an unlimited number of sub-elements, which are blocks, the generated class Statement
contains a getter getBlock()
, which returns a List<Block>
. To tell it again: JAXB generates another representation, which is much easier to process than a XML string, containing every detail from the XML. This is effected without any implementation by the framework.
The JAXB-based tree is then transformed to the AST, which is well suited for analysis and code generation. One nasty thing is, that some information from blockly must be saved into each AST-object. This is needed (in case of user errors, e.g.) to create feedback for the user, because we want to show the feedback attached to the graphical blocks the user had created. Thus an object of class BlocklyBlockProperties
is stored in each AST-object exactly for that purpose.
The AST of the expression 1+2
is shown below. Green is the top-level object for the binary op. It contains three beans for the left and right operand and for the operation ADD
. These are coloured orange. Each of these sub-beans contain a concrete value, the numeric constant resp. the operator name. These values are coloured yellow. Expression can be nested to any depth required, of course. The AST can be checked for consistency, analysed and used for code generation.
Have a look at the unit test Expr1add2Test
in project RobotMbed
and you can follow each step described above in detail by stepping through the test code with an IDE debugger. The RobotMbed
project was chosen to have access to a concrete code generator. The CalliopeCppVisitor
is used, which generates C++ code.
- when writing an action block (robActions.js) in order to make it change the port dynamically add the following lines to the init function of the block:
var ports = getConfigPorts('conf_block_title_in_lower_case');
this.dependConfig = {
'type' : 'conf_block_title_in_lower_case',
'dropDown' : ports
};
conf_block_title_in_lower_case can be found in the configuration block definition (robConfigDefinitions.js) as property 'title', just put it in lower case.
For example:
confBlocks.plotting = {}
confBlocks.plotting.sensebox = {
title : 'PLOTTING',
here the title is PLOTTING, so to make the plot_point block dynamically update the port the following is needed:
Blockly.Blocks['robActions_plot_point'] = {
init : function() {
this.setColour(Blockly.CAT_ACTION_RGB);
var dropDownPorts = getConfigPorts('plotting');
this.dependConfig = {
'type' : 'plotting',
'dropDown' : dropDownPorts
};
Home | Community | Installation | Team
Installation Tutorials
- Instructions to run a openroberta lab server using DOCKER
- Instructions to run the Open Roberta Lab Server natively on ubuntu ‐ not recommended
- Raspberry Pi 2/3/4 and the Open Roberta Lab
- EV3 and leJOS
- EV3 and ev3dev
- Creating the OR leJOS image
- Arduino Create Agent
- Mbed DAL: Generation and automation
Development
-
Workflows
-
Architecture
-
Blockly
-
Software engineering issues
-
Misc
-
Notes on robots
Textual Representation
Contribution
Discussions on future development