Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f5c6b60
Initial mechanisms and components
alan412 Apr 9, 2025
ca4f7e4
Can now increase/decrease inputs on mechanisms and components
alan412 Apr 10, 2025
62286fa
Generate Python for mechanisms and components
alan412 Apr 10, 2025
35eb4dd
Fix errors
alan412 Apr 10, 2025
f922325
Fixed where holder had to be before init to generate correctly
alan412 Apr 10, 2025
a02535a
Merge branch 'main' into pr_robot_mechanism_component
alan412 Apr 11, 2025
beed3d9
Move to have components and mechanisms like statements
alan412 Apr 11, 2025
1bdb642
remove unneeded files
alan412 Apr 11, 2025
3a8c4ea
Fixes typos
alan412 Apr 12, 2025
bfbdd22
add more sample components to hardware category
alan412 Apr 12, 2025
d48aebe
Changes to add ports, get things more like we want
alan412 Apr 26, 2025
e739152
added update method
alan412 Apr 26, 2025
7074b79
change orders and names of samples
alan412 Apr 26, 2025
c104f18
change defaults for mechanism_start (for screenshot)
alan412 Apr 26, 2025
57b47db
Have ports being passed in
alan412 May 3, 2025
70e76c5
add list of ports needed for mechanism
alan412 May 3, 2025
624db2b
Clear the list of ports in finish
alan412 May 3, 2025
b9b53c7
Remove the temporary init fields
alan412 May 3, 2025
8fa5612
No longer allow multiple components or mechanisms named the same
alan412 May 3, 2025
d3fe869
Change leftover cut/paste error
alan412 May 3, 2025
828c76d
Add details to OpMode
alan412 May 4, 2025
d363b10
Fixed output for non-opmodes
alan412 May 4, 2025
b495146
Fix passing the correct thing to superclass init
alan412 May 4, 2025
0f89813
Removed some unnecessary code
alan412 May 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/blocks/mrc_class_method_def.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,8 @@ export const pythonFromBlock = function (
xfix2 = xfix1;
}
if(block.mrcPythonMethodName == '__init__'){
branch = generator.INDENT + 'super().__init__(robot)\n' +
let class_specific = generator.getClassSpecificForInit();
branch = generator.INDENT + 'super().__init__(' + class_specific + ')\n' +
generator.defineClassVariables() + branch;
}
if (returnValue) {
Expand All @@ -469,6 +470,10 @@ export const pythonFromBlock = function (

let params = block.mrcParameters;
let paramString = "self";
if (block.mrcPythonMethodName == '__init__') {
paramString += generator.getListOfPorts(false);
}

if (params.length != 0) {
block.mrcParameters.forEach((param) => {
paramString += ', ' + param.name;
Expand Down
156 changes: 156 additions & 0 deletions src/blocks/mrc_component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* @license
* Copyright 2025 Porpoiseful LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @fileoverview Create a component with a name of a certain type
* @author [email protected] (Alan Smith)
*/
import * as Blockly from 'blockly';
import { Order } from 'blockly/python';

import { MRC_STYLE_COMPONENTS } from '../themes/styles'
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
import { getAllowedTypesForSetCheck } from './utils/python';

export const BLOCK_NAME = 'mrc_component';
export const OUTPUT_NAME = 'mrc_component';

export type ConstructorArg = {
name: string,
type: string,
};

type ComponentExtraState = {
importModule?: string,
hideParams?: boolean,
params?: ConstructorArg[],
}

type ComponentBlock = Blockly.Block & ComponentMixin;
interface ComponentMixin extends ComponentMixinType {
mrcArgs: ConstructorArg[],
hideParams: boolean,
mrcImportModule: string,
}
type ComponentMixinType = typeof COMPONENT;

const COMPONENT = {
/**
* Block initialization.
*/
init: function (this: ComponentBlock): void {
this.setStyle(MRC_STYLE_COMPONENTS);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('my_mech'), 'NAME')
.appendField('of type')
.appendField(createFieldNonEditableText(''), 'TYPE');
this.setPreviousStatement(true, OUTPUT_NAME);
this.setNextStatement(true, OUTPUT_NAME);
},

/**
* Returns the state of this block as a JSON serializable object.
*/
saveExtraState: function (this: ComponentBlock): ComponentExtraState {
const extraState: ComponentExtraState = {
};
extraState.params = [];
this.mrcArgs.forEach((arg) => {
extraState.params!.push({
'name': arg.name,
'type': arg.type,
});
});
if (this.mrcImportModule) {
extraState.importModule = this.mrcImportModule;
}
if (this.hideParams) {
extraState.hideParams = this.hideParams;
}
return extraState;
},
/**
* Applies the given state to this block.
*/
loadExtraState: function (this: ComponentBlock, extraState: ComponentExtraState): void {
this.mrcImportModule = extraState.importModule ? extraState.importModule : '';
this.hideParams = extraState.hideParams ? extraState.hideParams : false;
this.mrcArgs = [];

if (extraState.params) {
extraState.params.forEach((arg) => {
this.mrcArgs.push({
'name': arg.name,
'type': arg.type,
});
});
}
this.mrcArgs = extraState.params ? extraState.params : [];
this.updateBlock_();
},
/**
* Update the block to reflect the newly loaded extra state.
*/
updateBlock_: function (this: ComponentBlock): void {
if (this.hideParams == false) {
// Add input sockets for the arguments.
for (let i = 0; i < this.mrcArgs.length; i++) {
const input = this.appendValueInput('ARG' + i)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(this.mrcArgs[i].name);
if (this.mrcArgs[i].type) {
input.setCheck(getAllowedTypesForSetCheck(this.mrcArgs[i].type));
}
}
}
}
}

export const setup = function () {
Blockly.Blocks[BLOCK_NAME] = COMPONENT;
}

export const pythonFromBlock = function (
block: ComponentBlock,
generator: ExtendedPythonGenerator,
) {
if (block.mrcImportModule) {
generator.addImport(block.mrcImportModule);
}
let code = 'self.' + block.getFieldValue('NAME') + ' = ' + block.getFieldValue('TYPE') + '(';

for (let i = 0; i < block.mrcArgs.length; i++) {
const fieldName = 'ARG' + i;
if (i != 0) {
code += ', '
}
if(block.hideParams){
let extension = '';
if(i != 0){
extension = '_' + (i + 1).toString();
}
const newPort = block.getFieldValue('NAME') + extension + '_port';
generator.addHardwarePort(newPort, block.mrcArgs[i].type);
code += block.mrcArgs[i].name + " = " + newPort;
}else{
code += block.mrcArgs[i].name + ' = ' + generator.valueToCode(block, fieldName, Order.NONE);
}
}
code += ')\n' + "self.hardware.append(self." + block.getFieldValue('NAME') + ")\n";
return code;
}
66 changes: 32 additions & 34 deletions src/blocks/mrc_mechanism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import * as Blockly from 'blockly';
import { Order } from 'blockly/python';

import { MRC_STYLE_FUNCTIONS } from '../themes/styles'
import { MRC_STYLE_MECHANISMS } from '../themes/styles'
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
import { getAllowedTypesForSetCheck } from './utils/python';
Expand All @@ -44,22 +44,22 @@ type MechanismBlock = Blockly.Block & MechanismMixin;
interface MechanismMixin extends MechanismMixinType {
mrcArgs: ConstructorArg[],
mrcImportModule: string,

}
type MechanismMixinType = typeof MECHANISM_FUNCTION;
type MechanismMixinType = typeof MECHANISM;

const MECHANISM_FUNCTION = {
const MECHANISM = {
/**
* Block initialization.
*/
init: function (this: MechanismBlock): void {
this.setStyle(MRC_STYLE_FUNCTIONS);
this.setStyle(MRC_STYLE_MECHANISMS);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('my_mech'), 'NAME')
.appendField('of type')
.appendField(createFieldNonEditableText(''), 'TYPE');
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setPreviousStatement(true, OUTPUT_NAME);
this.setNextStatement(true, OUTPUT_NAME);
//this.setOutput(true, OUTPUT_NAME);
},

/**
Expand All @@ -74,7 +74,7 @@ const MECHANISM_FUNCTION = {
'name': arg.name,
'type': arg.type,
});
});
});
if (this.mrcImportModule) {
extraState.importModule = this.mrcImportModule;
}
Expand All @@ -87,7 +87,7 @@ const MECHANISM_FUNCTION = {
this.mrcImportModule = extraState.importModule ? extraState.importModule : '';
this.mrcArgs = [];

if(extraState.params){
if (extraState.params) {
extraState.params.forEach((arg) => {
this.mrcArgs.push({
'name': arg.name,
Expand All @@ -101,42 +101,40 @@ const MECHANISM_FUNCTION = {
/**
* Update the block to reflect the newly loaded extra state.
*/
updateBlock_: function(this: MechanismBlock): void {
// Add input sockets for the arguments.
for (let i = 0; i < this.mrcArgs.length; i++) {
const input = this.appendValueInput('ARG' + i)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(this.mrcArgs[i].name);
if (this.mrcArgs[i].type) {
input.setCheck(getAllowedTypesForSetCheck(this.mrcArgs[i].type));
}
updateBlock_: function (this: MechanismBlock): void {
// Add input sockets for the arguments.
for (let i = 0; i < this.mrcArgs.length; i++) {
const input = this.appendValueInput('ARG' + i)
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField(this.mrcArgs[i].name);
if (this.mrcArgs[i].type) {
input.setCheck(getAllowedTypesForSetCheck(this.mrcArgs[i].type));
}
}
}
}

export const setup = function () {
Blockly.Blocks[BLOCK_NAME] = MECHANISM_FUNCTION;
Blockly.Blocks[BLOCK_NAME] = MECHANISM;
}

export const pythonFromBlock = function (
mechanismBlock: MechanismBlock,
block: MechanismBlock,
generator: ExtendedPythonGenerator,
) {
if (mechanismBlock.mrcImportModule) {
generator.addImport(mechanismBlock.mrcImportModule);
if (block.mrcImportModule) {
generator.addImport(block.mrcImportModule);
}
generator.setHasMechanism();
let code = 'self.mechanisms["' + mechanismBlock.getFieldValue('NAME') + '"] = '
+ mechanismBlock.getFieldValue('TYPE') + '('
for (let i = 0; i < mechanismBlock.mrcArgs.length; i++) {
const fieldName = 'ARG' + i;
if(i != 0){
code += ', '
}
code += mechanismBlock.mrcArgs[i].name + ' = ' + generator.valueToCode(mechanismBlock, fieldName, Order.NONE);
let code = 'self.' + block.getFieldValue('NAME') + ' = ' + block.getFieldValue('TYPE') + '(';

for (let i = 0; i < block.mrcArgs.length; i++) {
const fieldName = 'ARG' + i;
if (i != 0) {
code += ', '
}

code += ')' + "\n";
code += block.mrcArgs[i].name + ' = ' + generator.valueToCode(block, fieldName, Order.NONE);
}
code += ')\n' + "self.hardware.append(self." + block.getFieldValue('NAME') + ")\n";

return code
return code;
}
Loading