Periodic Function

In the XRP curriculum, there is a suggestion to use machine.Timer in micropython to update the value logged in a webserver. However, there is no equivalent for Blockly.

I feel like adding a periodic function that runs would be a nice solution, even if it would be possible to also use a while loop. The problem with a while loop is that other code can’t be used concurrently: If one wanted to do something like logging values periodically while also traversing a complicated maze directly without sensors and just preprogrammed instructions, they would not be able to use while loops.

When using pestolink, there is also some delay to when servos move if the drivetrain is also being used. This idea should help mitigate this delay, not to mention it is similar to the command based structure of actual FRC.

It is a more elegant solution than while loops, and would be a helpful feature.

Blockly.Python['run_function_periodically'] = function(block) {
  // TODO: change Order.ATOMIC to the correct operator precedence strength
  PY.definitions_['import_timer'] = 'from machine import Timer \n\n timers=[]';
  const value_after = Blockly.Python.valueToCode(block, 'AFTER', Blockly.Python.ORDER_ATOMIC);
  const statement_do = Blockly.Python.statementToCode(block, 'DO');
  var funcName = getFuncName();
  var code = `\ndef ${funcName}():\n${statement_do}\ntimers.append(Timer(-1)); timers[-1].init(period=${value_after}, mode=Timer.PERIODIC, callback=${funcName})`

  return code;
}

The above is the python generator implementation of how it could work, using getFunction similar to web servers.

Blockly.Blocks['run_function_periodically'] = {
  init: function() {
    this.appendValueInput('AFTER')
    .appendField('After')
    .setCheck('Number');
    this.appendDummyInput()
    .appendField('seconds,');
    this.appendStatementInput('DO')
    .appendField('Do');
    this.setInputsInline(true)
    this.setTooltip('');
    this.setHelpUrl('');
    this.setColour(120);
  }
};

Above is the base generator form. I have tested it, and it generates the correct code. Ideally it would be placed in the loops section.

You have a lot of good ideas keep them coming. You are also very good at having ideas that hit the corners of tech and philosophy.

On the tech side, one of the things that makes command structure work well is being on a processor where a lot can happen in 20ms, giving a good combination of control and accuracy. The 2040 microprocessor has some problems with that and interrupting the blocking drivetrain calls starts to loose accuracy. But, maybe that is in the good lessons to learn category.

On the philosophy side is how complicated of programs do we enable in Blockly? There is a certain level of complexity and control you can only get from a syntax based language like Python. But, maybe people are enjoying Blockly programming so much that we should keep them in the flow and let them build ever more complex programs that way?

Thanks for the compliments! It’s my first year of going so deep into robotics and programming, so it does mean a lot.

It does make sense that the processor is the reason for why the xrps were unable to do both actions at once. I really am not experienced in the hardware side of things, so I’m not entirely sure how to mitigate this. However, using periodic callbacks should theoretically help, yet I haven’t tested it yet.

As for the philosophical side, I feel that it would be a good idea to allow students to go more in depth into the backbones of micropython while still using blockly’s simple interface. Not to mention the complexity of new blocks added is relative: from someone who understands programming and micropython may understand how complicated the logic behind blocks can be, but they would be able to use micropython themselves.

The real use is for younger less experienced students: most students don’t know that things are complicated to implement, and something intuitive as running code on a button press becomes vastly harder to program in without the use of some other software designed to make control easy. This obviously would cause frustration if the feature was not implemented, as such a “simple” feature isn’t available. The higher level Blockly code means that it can act in a role similar to scratch, allowing difficult code to be watered down so that people don’t have to worry about vectors or such.

A potential way to avoid needing to add dozens upon dozens of blocks to match micropython’s potential would be to add a block that can take in text input and convert it to Python code. By allowing someone to write custom code, people such as mentors can write the backbones of a program or perhaps functions to allow XRPs to do things not possible within the scope of Blockly, which can then be used by the children.

For example, a mentor could write a block that takes in pesto link input, put it in a function, and students could just call that block instead of using web servers, which don’t have good controller support. It would also mean that said mentor would not need to dig into the source code and make modifications there.

Blockly.Blocks['python_code'] = {
  init: function() {
    this.appendValueInput("CODE")
        .setCheck("String")
        .appendField("Add Python Code");
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(200);
 this.setTooltip("Adds a line of Python code to the generated program.");
 this.setHelpUrl("");
  }
};
Blockly.Python['python_code'] = function(block) {
  var value_name = Blockly.Python.valueToCode(block, 'CODE', python.Order.ATOMIC);
  // TODO: Assemble python into code variable.
  return value_name.substring(1, value_name.length-1);
};

The code above shows how it is possible to directly input python code. Preferably, it would be possible for there to be a custom “block creator” where people can just create a block themselves using python code, but I don’t have enough knowledge about Blockly to code all of that.