diff --git a/OpenRobertaServer/staticResources/blockly/blocks/lists.js b/OpenRobertaServer/staticResources/blockly/blocks/lists.js
index 424b71b07..53938ce6a 100644
--- a/OpenRobertaServer/staticResources/blockly/blocks/lists.js
+++ b/OpenRobertaServer/staticResources/blockly/blocks/lists.js
@@ -176,11 +176,12 @@ Blockly.Blocks['robLists_create_with'] = {
this.sourceBlock_.updateType_(option);
}
});
+ listType.setValue(this.listType_);
if (num == 1) {
if (this.itemCount_ == 0) {
this.removeInput('EMPTY');
this.appendValueInput('ADD0').appendField(Blockly.Msg.LISTS_CREATE_TITLE).appendField(':').appendField(listType, 'LIST_TYPE').appendField(
- Blockly.RTL ? '\u2192' : '\u2190').setCheck('Number');
+ Blockly.RTL ? '\u2192' : '\u2190').setCheck(this.listType_);
this.setInputsInline(false);
this.setMutatorMinus(new Blockly.MutatorMinus(this));
} else {
@@ -380,8 +381,7 @@ Blockly.Blocks['lists_getIndex'] = {
});
},
/**
- * Create XML to represent whether the block is a statement or a value. Also
- * represent whether there is an 'AT' input.
+ * Create XML to represent whether the block is a statement or a value. Also represent whether there is an 'AT' input.
*
* @return {Element} XML storage element.
* @this Blockly.Block
@@ -412,8 +412,7 @@ Blockly.Blocks['lists_getIndex'] = {
* Switch between a value block and a statement block.
*
* @param {boolean}
- * newStatement True if the block should be a statement. False if
- * the block should be a value.
+ * newStatement True if the block should be a statement. False if the block should be a value.
* @private
* @this Blockly.Block
*/
@@ -621,8 +620,7 @@ Blockly.Blocks['lists_getSublist'] = {
this.updateAt_(2, isAt2);
},
/**
- * Create or delete an input for a numeric index. This block has two such
- * inputs, independant of each other.
+ * Create or delete an input for a numeric index. This block has two such inputs, independant of each other.
*
* @param {number}
* n Specify first or second input (1 or 2).
diff --git a/OpenRobertaServer/staticResources/index.html b/OpenRobertaServer/staticResources/index.html
index 0fd13d22e..3ec144a92 100644
--- a/OpenRobertaServer/staticResources/index.html
+++ b/OpenRobertaServer/staticResources/index.html
@@ -34,24 +34,24 @@
-
+
+ -->
+
-
-
+
+
-
+
diff --git a/OpenRobertaServer/staticResources/roberta/roberta.js b/OpenRobertaServer/staticResources/roberta/roberta.js
index 3f330c908..c8e102a17 100644
--- a/OpenRobertaServer/staticResources/roberta/roberta.js
+++ b/OpenRobertaServer/staticResources/roberta/roberta.js
@@ -171,7 +171,11 @@ function showUserInfo() {
*/
function showRobotInfo() {
if (userState.robotName) {
- $("#robotName").text(userState.robotName);
+ if (userState.robot === "oraSim") {
+ $("#robotName").text("ORSim");
+ } else {
+ $("#robotName").text(userState.robotName);
+ }
if (userState.robotState === "wait") {
$("#robotStateWait").css('display', 'inline');
$("#robotStateDisconnected").css('display', 'none');
@@ -239,6 +243,13 @@ function injectBlockly(toolbox, opt_programBlocks, opt_readOnly) {
initProgramEnvironment(opt_programBlocks);
setRobotState(toolbox);
}
+ if (userState.robot === "ev3") {
+ $('#menuShowCode').parent().removeClass('disabled');
+ Blockly.getMainWorkspace().codeButton.enable();
+ } else {
+ $('#menuShowCode').parent().addClass('disabled');
+ Blockly.getMainWorkspace().codeButton.disable();
+ }
}
}
@@ -1150,11 +1161,32 @@ function switchToBrickly() {
$('#tabBrickly').click();
bricklyActive = true;
}
+/**
+ * Init robot
+ */
+function initRobot() {
+ ROBOT.setRobot(userState.robot, function(result) {
+ response(result);
+ if (result.rc === "ok") {
+ setConfiguration("EV3basis");
+ loadToolbox(userState.toolbox);
+ $('#blocklyDiv').removeClass('simBackground');
+ $('#menuEv3').parent().addClass('disabled');
+ $('#menuSim').parent().removeClass('disabled');
+ $('#menuConnect').parent().removeClass('disabled');
+ $('#iconDisplayRobotState').removeClass('typcn-Roberta');
+ $('#iconDisplayRobotState').addClass('typcn-ev3');
+ $('#menuShowCode').parent().removeClass('disabled');
+ }
+ });
+}
/**
* Switch robot
*/
function switchRobot(robot) {
+ if (robot === userState.robot)
+ return;
ROBOT.setRobot(robot, function(result) {
if (result.rc === "ok") {
userState.robot = robot;
@@ -1171,7 +1203,6 @@ function switchRobot(robot) {
Blockly.getMainWorkspace().codeButton.enable();
UTIL.getBricklyFrame('#bricklyFrame').loadToolboxAndConfiguration();
} else if (robot === "oraSim") {
- userState.robotName = "ORSim";
setConfiguration("ORSim");
$('#blocklyDiv').addClass('simBackground');
$('#menuEv3').parent().removeClass('disabled');
@@ -2100,7 +2131,7 @@ function init() {
// TODO do more?
}
});
- switchRobot(userState.robot);
+ initRobot();
COMM.json("/toolbox", {
"cmd" : "loadT",
"name" : userState.toolbox,
diff --git a/OpenRobertaServer/staticResources/simulation/robertaLogic/robertaLogic.min.js b/OpenRobertaServer/staticResources/simulation/robertaLogic/robertaLogic.min.js
index a2857b9a1..e3fca082d 100644
--- a/OpenRobertaServer/staticResources/simulation/robertaLogic/robertaLogic.min.js
+++ b/OpenRobertaServer/staticResources/simulation/robertaLogic/robertaLogic.min.js
@@ -1 +1 @@
-function Timer(){this.startTime=0,this.currentTime=0,this.time=0}function Motor(){this.power=0,this.stopped=!1,this.startRotations=0,this.currentRotations=0,this.rotations=0}function createConstant(a,b){var c={};return c[EXPR]=a,c[VALUE]=b,c}function createBinaryExpr(a,b,c){var d={};return d[EXPR]=BINARY,d[OP]=a,d[LEFT]=b,d[RIGHT]=c,d}function createVarReference(a,b){var c={};return c[EXPR]=VAR,c[TYPE]=a,c[NAME]=b,c}function createVarDeclaration(a,b,c){var d={};return d[STMT]=VAR_DECLARATION,d[TYPE]=a,d[NAME]=b,d[VALUE]=c,d}function createAssignStmt(a,b){var c={};return c[STMT]=ASSIGN_STMT,c[NAME]=a,c[EXPR]=b,c}function createRepeatStmt(a,b,c){if(!Array.isArray(c))throw"Expression List is not List!";var d={};return d[MODE]=a,d[STMT]=REPEAT_STMT,d[EXPR]=b,d[STMT_LIST]=c,d}function createDriveAction(a,b,c){var d={};return d[STMT]=DRIVE_ACTION,d[SPEED]=a,d[DRIVE_DIRECTION]=b,d[DISTANCE]=c,d}function createMotorOnAction(a,b,c){var d={};return d[STMT]=MOTOR_ON_ACTION,d[SPEED]=a,d[MOTOR_SIDE]=b,d[MOTOR_DURATION]=c,d}function createDuration(a,b){var c={};return c[MOTOR_MOVE_MODE]=a,c[MOTOR_DURATION_VALUE]=b,c}function createTurnAction(a,b,c){var d={};return d[STMT]=TURN_ACTION,d[SPEED]=a,d[TURN_DIRECTION]=b,d[ANGLE]=c,d}function createTurnLight(a,b){var c={};return c[STMT]=TURN_LIGHT,c[COLOR]=a,c[MODE]=b,c}function createResetLight(){var a={};return a[STMT]=RESET_LIGHT,a}function createStopDrive(){var a={};return a[STMT]=STOP_DRIVE,a}function createStopMotorAction(a){var b={};return b[STMT]=MOTOR_STOP,b[MOTOR_SIDE]=a,b}function createGetSample(a,b){var c={};return c[EXPR]=GET_SAMPLE,c[SENSOR_TYPE]=a,c[SENSOR_MODE]=b,c}function createIfStmt(a,b,c){if(!Array.isArray(a))throw"Expression List is not List!";if(!Array.isArray(b))throw"Then List is not List!";return result={},result[STMT]=IF_STMT,result[EXPR_LIST]=a,result[THEN_LIST]=b,result[ELSE_STMTS]=c,result}function createWaitStmt(a){if(!Array.isArray(a))throw"Statement List is not a List!";var b={};return b[STMT]=WAIT_STMT,b[STATEMENTS]=a,b}function createWaitTimeStmt(a){var b={};return b[STMT]=WAIT_TIME_STMT,b[TIME]=a,b}function initProgram(a){MEM.clear(),PROGRAM_SIMULATION.setNextStatement(!0),PROGRAM_SIMULATION.setWait(!1),PROGRAM_SIMULATION.set(a),LIGHT.setMode(OFF),ACTORS.resetMotorsSpeed()}function setSensorActorValues(a){SENSORS.setTouchSensor(a.touch),SENSORS.setColor(a.color),SENSORS.setLight(a.light),SENSORS.setUltrasonicSensor(a.ultrasonic),ACTORS.getLeftMotor().setCurrentRotations(a.tacho[0]),ACTORS.getRightMotor().setCurrentRotations(a.tacho[1]),PROGRAM_SIMULATION.getTimer().setCurrentTime(a.time)}function step(a){if(setSensorActorValues(a),PROGRAM_SIMULATION.isNextStatement()){var b=PROGRAM_SIMULATION.getRemove();switch(b.stmt){case ASSIGN_STMT:var c=evalExpr(b.expr);MEM.assign(b.name,c);break;case VAR_DECLARATION:var c=evalExpr(b.value);MEM.decl(b.name,c);break;case IF_STMT:evalIf(b),step(a);break;case REPEAT_STMT:evalRepeat(b),step(a);break;case DRIVE_ACTION:evalDriveAction(a,b);break;case TURN_ACTION:evalTurnAction(a,b);break;case MOTOR_ON_ACTION:evalMotorOnAction(a,b);break;case WAIT_STMT:evalWaitStmt(b);break;case WAIT_TIME_STMT:evalWaitTime(a,b);break;case TURN_LIGHT:LIGHT.setColor(b.color),LIGHT.setMode(b.mode);break;case STOP_DRIVE:ACTORS.setSpeed(0);break;case MOTOR_STOP:evalMotorStopAction(b);break;case RESET_LIGHT:LIGHT.setColor(GREEN),LIGHT.setMode(OFF);break;default:throw"Invalid Statement "+b.stmt+"!"}}ACTORS.calculateCoveredDistance(),PROGRAM_SIMULATION.handleWaitTimer()}function evalWaitTime(a,b){PROGRAM_SIMULATION.setIsRunningTimer(!0),PROGRAM_SIMULATION.resetTimer(a.time),PROGRAM_SIMULATION.setTimer(evalExpr(b.time))}function evalTurnAction(a,b){ACTORS.resetTachoMotors(a.tacho[0],a.tacho[1]),ACTORS.setAngleSpeed(evalExpr(b.speed),b[TURN_DIRECTION]),setAngleToTurn(b)}function evalDriveAction(a,b){ACTORS.resetTachoMotors(a.tacho[0],a.tacho[1]),ACTORS.setSpeed(evalExpr(b.speed),b[DRIVE_DIRECTION]),setDistanceToDrive(b)}function evalMotorOnAction(a,b){b[MOTOR_SIDE]==MOTOR_LEFT?(ACTORS.resetLeftTachoMotor(a.tacho[0]),ACTORS.setLeftMotorSpeed(evalExpr(b.speed))):(ACTORS.resetRightTachoMotor(a.tacho[1]),ACTORS.setRightMotorSpeed(evalExpr(b.speed))),setDurationToCover(b)}function evalMotorStopAction(a){a[MOTOR_SIDE]==MOTOR_LEFT?ACTORS.setLeftMotorSpeed(0):ACTORS.setRightMotorSpeed(0)}function setAngleToTurn(a){void 0!=a.angle&&ACTORS.clculateAngleToCover(evalExpr(a.angle))}function setDistanceToDrive(a){void 0!=a.distance&&ACTORS.setDistanceToCover(evalExpr(a.distance))}function setDurationToCover(a){void 0!=a[MOTOR_DURATION]&&ACTORS.setMotorDuration(a[MOTOR_DURATION].motorMoveMode,evalExpr(a[MOTOR_DURATION].motorDurationValue),a[MOTOR_SIDE])}function evalRepeat(a){switch(a.mode){case TIMES:for(var b=0;bd;break;case GT:f=d>e;break;case EQ:f=d==e;break;case NEQ:f=d!=e;break;case GTE:f=d>=e;break;case LTE:f=e>=d;break;case OR:f=d||e;break;case AND:f=d&&e;break;default:throw"Invalid Binary Operator"}return f}const EXPR="expr",VALUE="value",OP="op",LEFT="left",RIGHT="right",BINARY="Binary",VAR="Var",TYPE="type",NAME="name",STMT="stmt",VAR_DECLARATION="VarDeclaration",ASSIGN_STMT="AssignStmt",REPEAT_STMT="RepeatStmt",IF_STMT="IfStatement",WAIT_STMT="WaitStmt",WAIT_TIME_STMT="WaitTimeSTMT",TIME="time",STMT_LIST="stmtList",DRIVE_ACTION="DriveAction",TURN_LIGHT="turnLight",TURN_ACTION="TurnAction",STOP_DRIVE="stopDrive",DRIVE_DIRECTION="driveDirection",TURN_DIRECTION="turnDirection",SPEED="speed",DISTANCE="distance",GET_SAMPLE="GetSample",SENSOR_TYPE="sensorType",SENSOR_MODE="sensorMode",THEN_LIST="thenList",ELSE_STMTS="elseStmts",EXPR_LIST="exprList",STATEMENTS="statements",TOUCH="TOUCH",ULTRASONIC="ULTRASONIC",NUM_CONST="NumConst",BOOL_CONST="BoolConst",NUMERIC="Numeric",ADD="ADD",MINUS="MINUS",POWER="POWER",DIVIDE="DIVIDE",MULTIPLY="MULTIPLY",LT="LT",GT="GT",EQ="EQ",NEQ="NEQ",GTE="GTE",LTE="LTE",OR="OR",AND="AND",FOREWARD="FOREWARD",BACKWARD="BACKWARD",WHILE="WHILE",FOREVER="FOREVER",ANGLE="angle",COLOR="color",COLOUR="COLOUR",MODE="mode",GREEN="GREEN",RED="RED",ORANGE="ORANGE",ON="ON",OFF="OFF",FLASH="FLASH",DOUBLE_FLASH="DOUBLE_FLASH",RESET_LIGHT="resetLight",TIMES="TIMES",COLOR_CONST="COLOR_CONST",PILOT="pilot",MOTOR_LEFT="C",MOTOR_RIGHT="B",MOTOR_SIDE="motorSide",MOTOR_ON_ACTION="motorOnAction",MOTOR_STOP="motorStop",MOTOR_MOVE_MODE="motorMoveMode",MOTOR_DURATION="motorDuration",MOTOR_DURATION_VALUE="motorDurationValue",ROTATIONS="ROTATIONS",DEGREE="DEGREE",COLOR_ENUM={NONE:0,BLACK:1,BLUE:2,GREEN:3,YELLOW:4,RED:5,WHITE:6,BROWN:7},TRACKWIDTH=40,TURN_RATIO=TRACKWIDTH/3/2.8,WHEEL_DIAMETER=5.6,MAXDIAG=2500,MAXPOWER=.35*3,ENC=360/(3*Math.PI*WHEEL_DIAMETER),MAX_WIDTH=2e3,MAX_HEIGHT=1e3,WAVE_LENGTH=60;Timer.prototype.setStartTime=function(a){this.startTime=a},Timer.prototype.getStartTime=function(){return this.startTime},Timer.prototype.setCurrentTime=function(a){this.currentTime=Math.abs(a-this.startTime)},Timer.prototype.getCurrentTime=function(){return this.currentTime},Timer.prototype.setTime=function(a){this.time=a},Timer.prototype.getTime=function(){return this.time},Motor.prototype.getPower=function(){return this.power},Motor.prototype.setPower=function(a){this.power=a},Motor.prototype.isStopped=function(){return this.stopped},Motor.prototype.setStopped=function(a){this.stopped=a},Motor.prototype.getCurrentRotations=function(){return this.currentRotations},Motor.prototype.setCurrentRotations=function(a){this.currentRotations=Math.abs(a/360-this.startRotations)},Motor.prototype.getRotations=function(){return this.rotations},Motor.prototype.setRotations=function(a){this.rotations=a};var SENSORS=function(){function e(){return a}function f(b){a=b}function g(){return b}function h(a){b=a}function i(a){c=a}function j(){return c}function k(a){d=a}function l(){return d}var a=!1,b=0,c=void 0,d=0;return{isPressed:e,setTouchSensor:f,getUltrasonicSensor:g,setUltrasonicSensor:h,setColor:i,getColor:j,setLight:k,getLight:l}}(),ACTORS=function(){function e(){return c}function f(){return d}function g(a,b){b!=FOREWARD&&(a=-a),c.setPower(a),d.setPower(a)}function h(a,b){b==LEFT?(c.setPower(-a),d.setPower(a)):(c.setPower(a),d.setPower(-a))}function i(a){c.startRotations=a/360,c.currentRotations=0}function j(a){d.startRotations=a/360,d.currentRotations=0}function k(a,b){i(a),j(b)}function l(){var b=e().getCurrentRotations()>e().getRotations(),c=f().getCurrentRotations()>f().getRotations();if(a)switch(driveMode){case PILOT:b&&c&&(e().setPower(0),f().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0));break;case MOTOR_LEFT:b&&(e().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0));break;case MOTOR_RIGHT:c&&(f().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0))}}function m(b){extraRotation=TURN_RATIO*(b/720),e().setRotations(extraRotation),f().setRotations(extraRotation),a=!0,driveMode=PILOT,PROGRAM_SIMULATION.setNextStatement(!1)}function n(b){var e=b/17.584;c.setRotations(e),d.setRotations(e),a=!0,driveMode=PILOT,PROGRAM_SIMULATION.setNextStatement(!1)}function o(a){c.setPower(a)}function p(a){d.setPower(a)}function q(b,e,f){var g=e;b==DEGREE&&(g=e/360),f==MOTOR_LEFT?(c.setRotations(g),driveMode=MOTOR_LEFT):(d.setRotations(g),driveMode=MOTOR_RIGHT),a=!0,PROGRAM_SIMULATION.setNextStatement(!1)}function r(){c.setPower(0),d.setPower(0)}function s(){return JSON.stringify([a,c,d])}var a=!1,c=new Motor,d=new Motor;return{getLeftMotor:e,getRightMotor:f,setSpeed:g,setAngleSpeed:h,resetLeftTachoMotor:i,resetRightTachoMotor:j,resetTachoMotors:k,calculateCoveredDistance:l,clculateAngleToCover:m,setDistanceToCover:n,setLeftMotorSpeed:o,setRightMotorSpeed:p,setMotorDuration:q,resetMotorsSpeed:r,toString:s}}(),MEM=function(){function b(b,c){if(void 0!=a[b])throw"Variable "+b+" is defined!";if(void 0==c)throw"Variable "+b+" not initialized!";a[b]=c}function c(b,c){if(void 0==a[b])throw"Variable "+b+" is undefined!";if(void 0==c)throw"Variable "+b+" not assigned!";a[b]=c}function d(b){if(void 0==a[b])throw"Variable "+b+" is undefined!";return a[b]}function e(){a={}}function f(){return JSON.stringify(a)}var a={};return{decl:b,assign:c,get:d,clear:e,toString:f}}(),PROGRAM_SIMULATION=function(){function f(b){a=b}function g(){return 0===a.length&&m()}function h(){if(0===a.length)throw"Program is empty!";return a[0]}function i(){if(0===a.length)throw"Program is empty!";var b=a[0];return a=a.slice(1,a.length),b}function j(b){void 0!=b&&(a=b.concat(a))}function k(){return c}function l(a){c=a}function m(){return b}function n(a){d.setStartTime(a),d.currentTime=0}function o(a){PROGRAM_SIMULATION.setNextStatement(!1),p().setTime(a/1e3)}function p(){return d}function q(){e&&p().getCurrentTime()>p().getTime()&&(e=!1,PROGRAM_SIMULATION.setNextStatement(!0))}function r(a){b=a}function s(){return e}function t(a){e=a}function u(){return JSON.stringify([a,d])}var a=[],b=!0,c=!1,d=new Timer,e=!1;return{set:f,isTerminated:g,get:h,getRemove:i,prepend:j,isWait:k,setWait:l,isNextStatement:m,setNextStatement:r,isRunningTimer:s,setIsRunningTimer:t,resetTimer:n,getTimer:p,setTimer:o,handleWaitTimer:q,toString:u}}(),LIGHT=function(){function c(b){a=b}function d(a){b=a}function e(){return a}function f(){return b}function g(){return JSON.stringify([a,b])}var a="",b=OFF;return{setColor:c,setMode:d,getColor:e,getMode:f,toString:g}}();
\ No newline at end of file
+function Timer(){this.startTime=0,this.currentTime=0,this.time=0}function Motor(){this.power=0,this.stopped=!1,this.startRotations=0,this.currentRotations=0,this.rotations=0}function createConstant(a,b){var c={};return c[EXPR]=a,c[VALUE]=b,c}function createBinaryExpr(a,b,c){var d={};return d[EXPR]=BINARY,d[OP]=a,d[LEFT]=b,d[RIGHT]=c,d}function createVarReference(a,b){var c={};return c[EXPR]=VAR,c[TYPE]=a,c[NAME]=b,c}function createVarDeclaration(a,b,c){var d={};return d[STMT]=VAR_DECLARATION,d[TYPE]=a,d[NAME]=b,d[VALUE]=c,d}function createAssignStmt(a,b){var c={};return c[STMT]=ASSIGN_STMT,c[NAME]=a,c[EXPR]=b,c}function createRepeatStmt(a,b,c){if(!Array.isArray(c))throw"Expression List is not List!";var d={};return d[MODE]=a,d[STMT]=REPEAT_STMT,d[EXPR]=b,d[STMT_LIST]=c,d}function createDriveAction(a,b,c){var d={};return d[STMT]=DRIVE_ACTION,d[SPEED]=a,d[DRIVE_DIRECTION]=b,d[DISTANCE]=c,d}function createMotorOnAction(a,b,c){var d={};return d[STMT]=MOTOR_ON_ACTION,d[SPEED]=a,d[MOTOR_SIDE]=b,d[MOTOR_DURATION]=c,d}function createDuration(a,b){var c={};return c[MOTOR_MOVE_MODE]=a,c[MOTOR_DURATION_VALUE]=b,c}function createTurnAction(a,b,c){var d={};return d[STMT]=TURN_ACTION,d[SPEED]=a,d[TURN_DIRECTION]=b,d[ANGLE]=c,d}function createTurnLight(a,b){var c={};return c[STMT]=TURN_LIGHT,c[COLOR]=a,c[MODE]=b,c}function createResetLight(){var a={};return a[STMT]=RESET_LIGHT,a}function createStopDrive(){var a={};return a[STMT]=STOP_DRIVE,a}function createStopMotorAction(a){var b={};return b[STMT]=MOTOR_STOP,b[MOTOR_SIDE]=a,b}function createGetSample(a,b){var c={};return c[EXPR]=GET_SAMPLE,c[SENSOR_TYPE]=a,c[SENSOR_MODE]=b,c}function createIfStmt(a,b,c){if(!Array.isArray(a))throw"Expression List is not List!";if(!Array.isArray(b))throw"Then List is not List!";return result={},result[STMT]=IF_STMT,result[EXPR_LIST]=a,result[THEN_LIST]=b,result[ELSE_STMTS]=c,result}function createWaitStmt(a){if(!Array.isArray(a))throw"Statement List is not a List!";var b={};return b[STMT]=WAIT_STMT,b[STATEMENTS]=a,b}function createWaitTimeStmt(a){var b={};return b[STMT]=WAIT_TIME_STMT,b[TIME]=a,b}function initProgram(a){MEM.clear(),PROGRAM_SIMULATION.setNextStatement(!0),PROGRAM_SIMULATION.setWait(!1),PROGRAM_SIMULATION.set(a),LIGHT.setMode(OFF),ACTORS.resetMotorsSpeed()}function setSensorActorValues(a){SENSORS.setTouchSensor(a.touch),SENSORS.setColor(a.color),SENSORS.setLight(a.light),SENSORS.setUltrasonicSensor(a.ultrasonic),ACTORS.getLeftMotor().setCurrentRotations(a.tacho[0]),ACTORS.getRightMotor().setCurrentRotations(a.tacho[1]),PROGRAM_SIMULATION.getTimer().setCurrentTime(a.time)}function step(a){if(setSensorActorValues(a),PROGRAM_SIMULATION.isNextStatement()){var b=PROGRAM_SIMULATION.getRemove();switch(b.stmt){case ASSIGN_STMT:var c=evalExpr(b.expr);MEM.assign(b.name,c);break;case VAR_DECLARATION:var c=evalExpr(b.value);MEM.decl(b.name,c);break;case IF_STMT:evalIf(b),step(a);break;case REPEAT_STMT:evalRepeat(b),step(a);break;case DRIVE_ACTION:evalDriveAction(a,b);break;case TURN_ACTION:evalTurnAction(a,b);break;case MOTOR_ON_ACTION:evalMotorOnAction(a,b);break;case WAIT_STMT:evalWaitStmt(b);break;case WAIT_TIME_STMT:evalWaitTime(a,b);break;case TURN_LIGHT:LIGHT.setColor(b.color),LIGHT.setMode(b.mode);break;case STOP_DRIVE:ACTORS.setSpeed(0);break;case MOTOR_STOP:evalMotorStopAction(b);break;case RESET_LIGHT:LIGHT.setColor(GREEN),LIGHT.setMode(OFF);break;default:throw"Invalid Statement "+b.stmt+"!"}}ACTORS.calculateCoveredDistance(),PROGRAM_SIMULATION.handleWaitTimer()}function evalWaitTime(a,b){PROGRAM_SIMULATION.setIsRunningTimer(!0),PROGRAM_SIMULATION.resetTimer(a.time),PROGRAM_SIMULATION.setTimer(evalExpr(b.time))}function evalTurnAction(a,b){ACTORS.resetTachoMotors(a.tacho[0],a.tacho[1]),ACTORS.setAngleSpeed(evalExpr(b.speed),b[TURN_DIRECTION]),setAngleToTurn(b)}function evalDriveAction(a,b){ACTORS.resetTachoMotors(a.tacho[0],a.tacho[1]),ACTORS.setSpeed(evalExpr(b.speed),b[DRIVE_DIRECTION]),setDistanceToDrive(b)}function evalMotorOnAction(a,b){b[MOTOR_SIDE]==MOTOR_LEFT?(ACTORS.resetLeftTachoMotor(a.tacho[0]),ACTORS.setLeftMotorSpeed(evalExpr(b.speed))):(ACTORS.resetRightTachoMotor(a.tacho[1]),ACTORS.setRightMotorSpeed(evalExpr(b.speed))),setDurationToCover(b)}function evalMotorStopAction(a){a[MOTOR_SIDE]==MOTOR_LEFT?ACTORS.setLeftMotorSpeed(0):ACTORS.setRightMotorSpeed(0)}function setAngleToTurn(a){void 0!=a.angle&&ACTORS.clculateAngleToCover(evalExpr(a.angle))}function setDistanceToDrive(a){void 0!=a.distance&&ACTORS.setDistanceToCover(evalExpr(a.distance))}function setDurationToCover(a){void 0!=a[MOTOR_DURATION]&&ACTORS.setMotorDuration(a[MOTOR_DURATION].motorMoveMode,evalExpr(a[MOTOR_DURATION].motorDurationValue),a[MOTOR_SIDE])}function evalRepeat(a){switch(a.mode){case TIMES:for(var b=0;bd;break;case GT:f=d>e;break;case EQ:f=d==e;break;case NEQ:f=d!=e;break;case GTE:f=d>=e;break;case LTE:f=e>=d;break;case OR:f=d||e;break;case AND:f=d&&e;break;default:throw"Invalid Binary Operator"}return f}const EXPR="expr",VALUE="value",OP="op",LEFT="left",RIGHT="right",BINARY="Binary",VAR="Var",TYPE="type",NAME="name",STMT="stmt",VAR_DECLARATION="VarDeclaration",ASSIGN_STMT="AssignStmt",REPEAT_STMT="RepeatStmt",IF_STMT="IfStatement",WAIT_STMT="WaitStmt",WAIT_TIME_STMT="WaitTimeSTMT",TIME="time",STMT_LIST="stmtList",DRIVE_ACTION="DriveAction",TURN_LIGHT="turnLight",TURN_ACTION="TurnAction",STOP_DRIVE="stopDrive",DRIVE_DIRECTION="driveDirection",TURN_DIRECTION="turnDirection",SPEED="speed",DISTANCE="distance",GET_SAMPLE="GetSample",SENSOR_TYPE="sensorType",SENSOR_MODE="sensorMode",THEN_LIST="thenList",ELSE_STMTS="elseStmts",EXPR_LIST="exprList",STATEMENTS="statements",TOUCH="TOUCH",ULTRASONIC="ULTRASONIC",NUM_CONST="NumConst",BOOL_CONST="BoolConst",NUMERIC="Numeric",ADD="ADD",MINUS="MINUS",POWER="POWER",DIVIDE="DIVIDE",MULTIPLY="MULTIPLY",LT="LT",GT="GT",EQ="EQ",NEQ="NEQ",GTE="GTE",LTE="LTE",OR="OR",AND="AND",FOREWARD="FOREWARD",BACKWARD="BACKWARD",WHILE="WHILE",FOREVER="FOREVER",ANGLE="angle",COLOR="color",COLOUR="COLOUR",MODE="mode",GREEN="GREEN",RED="RED",ORANGE="ORANGE",ON="ON",OFF="OFF",FLASH="FLASH",DOUBLE_FLASH="DOUBLE_FLASH",RESET_LIGHT="resetLight",TIMES="TIMES",COLOR_CONST="COLOR_CONST",PILOT="pilot",MOTOR_LEFT="C",MOTOR_RIGHT="B",MOTOR_SIDE="motorSide",MOTOR_ON_ACTION="motorOnAction",MOTOR_STOP="motorStop",MOTOR_MOVE_MODE="motorMoveMode",MOTOR_DURATION="motorDuration",MOTOR_DURATION_VALUE="motorDurationValue",ROTATIONS="ROTATIONS",DEGREE="DEGREE",COLOR_ENUM={NONE:0,BLACK:1,BLUE:2,GREEN:3,YELLOW:4,RED:5,WHITE:6,BROWN:7},TRACKWIDTH=40,TURN_RATIO=TRACKWIDTH/3/2.8,WHEEL_DIAMETER=5.6,MAXDIAG=2500,MAXPOWER=.35*3,ENC=360/(3*Math.PI*WHEEL_DIAMETER),MAX_WIDTH=2e3,MAX_HEIGHT=1e3,WAVE_LENGTH=60;Timer.prototype.setStartTime=function(a){this.startTime=a},Timer.prototype.getStartTime=function(){return this.startTime},Timer.prototype.setCurrentTime=function(a){this.currentTime=Math.abs(a-this.startTime)},Timer.prototype.getCurrentTime=function(){return this.currentTime},Timer.prototype.setTime=function(a){this.time=a},Timer.prototype.getTime=function(){return this.time},Motor.prototype.getPower=function(){return this.power},Motor.prototype.setPower=function(a){this.power=a},Motor.prototype.isStopped=function(){return this.stopped},Motor.prototype.setStopped=function(a){this.stopped=a},Motor.prototype.getCurrentRotations=function(){return this.currentRotations},Motor.prototype.setCurrentRotations=function(a){this.currentRotations=Math.abs(a/360-this.startRotations)},Motor.prototype.getRotations=function(){return this.rotations},Motor.prototype.setRotations=function(a){this.rotations=a};var SENSORS=function(){function e(){return a}function f(b){a=b}function g(){return b}function h(a){b=a}function i(a){c=a}function j(){return c}function k(a){d=a}function l(){return d}var a=!1,b=0,c=void 0,d=0;return{isPressed:e,setTouchSensor:f,getUltrasonicSensor:g,setUltrasonicSensor:h,setColor:i,getColor:j,setLight:k,getLight:l}}(),ACTORS=function(){function e(){return c}function f(){return d}function g(a,b){b!=FOREWARD&&(a=-a),c.setPower(a),d.setPower(a)}function h(a,b){b==LEFT?(c.setPower(-a),d.setPower(a)):(c.setPower(a),d.setPower(-a))}function i(a){c.startRotations=a/360,c.currentRotations=0}function j(a){d.startRotations=a/360,d.currentRotations=0}function k(a,b){i(a),j(b)}function l(){var b=e().getCurrentRotations()>e().getRotations(),c=f().getCurrentRotations()>f().getRotations();if(a)switch(driveMode){case PILOT:b&&c&&(e().setPower(0),f().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0));break;case MOTOR_LEFT:b&&(e().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0));break;case MOTOR_RIGHT:c&&(f().setPower(0),a=!1,PROGRAM_SIMULATION.setNextStatement(!0))}}function m(b){extraRotation=TURN_RATIO*(b/720),e().setRotations(extraRotation),f().setRotations(extraRotation),a=!0,driveMode=PILOT,PROGRAM_SIMULATION.setNextStatement(!1)}function n(b){var e=b/17.584;c.setRotations(e),d.setRotations(e),a=!0,driveMode=PILOT,PROGRAM_SIMULATION.setNextStatement(!1)}function o(a){c.setPower(a)}function p(a){d.setPower(a)}function q(b,e,f){var g=e;b==DEGREE&&(g=e/360),f==MOTOR_LEFT?(c.setRotations(g),driveMode=MOTOR_LEFT):(d.setRotations(g),driveMode=MOTOR_RIGHT),a=!0,PROGRAM_SIMULATION.setNextStatement(!1)}function r(){c.setPower(0),d.setPower(0)}function s(){return JSON.stringify([a,c,d])}var a=!1,c=new Motor,d=new Motor;return{getLeftMotor:e,getRightMotor:f,setSpeed:g,setAngleSpeed:h,resetLeftTachoMotor:i,resetRightTachoMotor:j,resetTachoMotors:k,calculateCoveredDistance:l,clculateAngleToCover:m,setDistanceToCover:n,setLeftMotorSpeed:o,setRightMotorSpeed:p,setMotorDuration:q,resetMotorsSpeed:r,toString:s}}(),MEM=function(){function b(b,c){if(void 0!=a[b])throw"Variable "+b+" is defined!";if(void 0==c)throw"Variable "+b+" not initialized!";a[b]=c}function c(b,c){if(void 0==a[b])throw"Variable "+b+" is undefined!";if(void 0==c)throw"Variable "+b+" not assigned!";a[b]=c}function d(b){if(void 0==a[b])throw"Variable "+b+" is undefined!";return a[b]}function e(){a={}}function f(){return JSON.stringify(a)}var a={};return{decl:b,assign:c,get:d,clear:e,toString:f}}(),PROGRAM_SIMULATION=function(){function f(b){a=b}function g(){return 0===a.length&&m()}function h(){if(0===a.length)throw"Program is empty!";return a[0]}function i(){if(0===a.length)throw"Program is empty!";var b=a[0];return a=a.slice(1,a.length),b}function j(b){void 0!=b&&(a=b.concat(a))}function k(){return c}function l(a){c=a}function m(){return b}function n(a){d.setStartTime(a),d.currentTime=0}function o(a){PROGRAM_SIMULATION.setNextStatement(!1),p().setTime(a/1e3)}function p(){return d}function q(){e&&p().getCurrentTime()>p().getTime()&&(e=!1,PROGRAM_SIMULATION.setNextStatement(!0))}function r(a){b=a}function s(){return e}function t(a){e=a}function u(){return JSON.stringify([a,d])}var a=[],b=!0,c=!1,d=new Timer,e=!1;return{set:f,isTerminated:g,get:h,getRemove:i,prepend:j,isWait:k,setWait:l,isNextStatement:m,setNextStatement:r,isRunningTimer:s,setIsRunningTimer:t,resetTimer:n,getTimer:p,setTimer:o,handleWaitTimer:q,toString:u}}(),LIGHT=function(){function c(b){a=b}function d(a){b=a}function e(){return a}function f(){return b}function g(){return JSON.stringify([a,b])}var a="",b=OFF;return{setColor:c,setMode:d,getColor:e,getMode:f,toString:g}}();
\ No newline at end of file
diff --git a/OpenRobertaServer/staticResources/simulation/simulationLogic/simulation.js b/OpenRobertaServer/staticResources/simulation/simulationLogic/simulation.js
index 785553963..4b7c00945 100644
--- a/OpenRobertaServer/staticResources/simulation/simulationLogic/simulation.js
+++ b/OpenRobertaServer/staticResources/simulation/simulationLogic/simulation.js
@@ -222,8 +222,20 @@ var SIM = (function() {
}
function setOutput() {
- output.left = ACTORS.getLeftMotor().getPower() * MAXPOWER || 0;
- output.right = ACTORS.getRightMotor().getPower() * MAXPOWER || 0;
+ var left = ACTORS.getLeftMotor().getPower();
+ if (left > 100) {
+ left = 100;
+ } else if (left < -100) {
+ left = -100
+ }
+ var right = ACTORS.getRightMotor().getPower();
+ if (right > 100) {
+ right = 100;
+ } else if (right < -100) {
+ right = -100
+ }
+ output.left = left * MAXPOWER || 0;
+ output.right = right * MAXPOWER || 0;
robot.led.mode = output.ledMode = LIGHT.getMode() || "OFF";
if (LIGHT.getMode() && LIGHT.getMode() == "OFF") {
diff --git a/OpenRobertaServer/staticResources/simulation/simulationLogic/simulationLogic.min.js b/OpenRobertaServer/staticResources/simulation/simulationLogic/simulationLogic.min.js
index c9ef92b38..68afcc4d9 100644
--- a/OpenRobertaServer/staticResources/simulation/simulationLogic/simulationLogic.min.js
+++ b/OpenRobertaServer/staticResources/simulation/simulationLogic/simulationLogic.min.js
@@ -1 +1 @@
-function Robot(a){this.pose=a;var b={x:a.x,y:a.y,theta:a.theta,transX:a.transX,transY:a.transY};this.reset=function(){this.pose.x=b.x,this.pose.y=b.y,this.pose.theta=b.theta,this.pose.xOld=b.x,this.pose.yOld=b.y,this.pose.thetaOld=b.theta,this.pose.transX=b.transX,this.pose.transY=b.transY,this.encoder.left=0,this.encoder.right=0,this.led.color="#dddddd",this.led.mode=OFF,this.time=0}}function SimpleRobot(){Robot.call(this,{x:240,y:200,theta:0,xOld:240,yOld:200,transX:0,transY:0})}function RobertaRobot(){Robot.call(this,{x:70,y:90,theta:0,xOld:70,yOld:90,transX:0,transY:0})}function RescueRobot(){Robot.call(this,{x:400,y:40,theta:0,xOld:400,yOld:40,transX:0,transY:0})}function DrawRobot(){Robot.call(this,{x:200,y:200,theta:0,xOld:200,yOld:200,transX:0,transY:0}),this.canDraw=!0,this.drawColor="#000000",this.drawWidth=10}function MathRobot(){Robot.call(this,{x:400,y:250,theta:0,xOld:400,yOld:250,transX:-400,transY:-250}),this.canDraw=!0,this.drawColor="#ffffff",this.drawWidth=1}function Scene(a,b,c,d){this.backgroundImg=a,this.robot=c,this.obstacle=d,this.uCtx=b[0],this.bCtx=b[1],this.oCtx=b[2],this.rCtx=b[3],this.playground={x:0,y:0,w:0,h:0},this.wave=0}Robot.prototype.geom={x:-20,y:-20,w:40,h:50,color:"#FCCC00"},Robot.prototype.wheelLeft={x:16,y:-8,w:8,h:16,color:"#000000"},Robot.prototype.wheelRight={x:-24,y:-8,w:8,h:16,color:"#000000"},Robot.prototype.wheelBack={x:-2.5,y:30,w:5,h:5,color:"#000000"},Robot.prototype.led={x:0,y:10,color:"#dddddd",mode:""},Robot.prototype.encoder={left:0,right:0},Robot.prototype.colorSensor={x:0,y:-15,rx:0,ry:0,r:5,colorValue:0,color:"grey"},Robot.prototype.lightSensor={x:0,y:-15,rx:0,ry:0,r:5,lightValue:0},Robot.prototype.ultraSensor={x:0,y:-20,rx:0,ry:0,distance:0,u:[],cx:0,cy:0,color:"#FF69B4"},Robot.prototype.touchSensor={x:0,y:-25,x1:0,y1:0,x2:0,y2:0,value:0,color:"#FFCC33"},Robot.prototype.frontLeft={x:22.5,y:-25,rx:0,ry:0,bumped:!1},Robot.prototype.frontRight={x:-22.5,y:-25,rx:0,ry:0,bumped:!1},Robot.prototype.backLeft={x:20,y:30,rx:0,ry:0,bumped:!1},Robot.prototype.backRight={x:-20,y:30,rx:0,ry:0,bumped:!1},Robot.prototype.backMiddle={x:0,y:30,rx:0,ry:0},Robot.prototype.mouse={x:0,y:5,rx:0,ry:0,r:30},Robot.prototype.time=0,Robot.prototype.updatePose=function(a){if(this.pose.theta=(this.pose.theta+2*Math.PI)%(2*Math.PI),this.encoder.left+=a.left*SIM.getDt(),this.encoder.right+=a.right*SIM.getDt(),this.bumpedAready=!1,this.frontLeft.bumped&&a.left>0&&(a.left*=-1,this.bumpedAready=!0),this.backLeft.bumped&&a.left<0&&(a.left*=-1,this.bumpedAready=!0),this.frontRight.bumped&&a.right>0&&(a.right*=-1,this.bumpedAready=!0),this.backRight.bumped&&a.right<0&&(a.right*=-1,this.bumpedAready=!0),a.right==a.left){var b=a.right*SIM.getDt(),c=Math.cos(this.pose.theta)*b,d=Math.sqrt(Math.pow(b,2)-Math.pow(c,2));this.pose.x+=c,b>=0?this.pose.thetaMath.PI?this.pose.y+=d:this.pose.y-=d}else{var e=TRACKWIDTH/2*((a.left+a.right)/(a.left-a.right)),f=(a.left-a.right)/TRACKWIDTH,g=this.pose.x-e*Math.sin(this.pose.theta),h=this.pose.y+e*Math.cos(this.pose.theta);this.pose.x=Math.cos(f*SIM.getDt())*(this.pose.x-g)-Math.sin(f*SIM.getDt())*(this.pose.y-h)+g,this.pose.y=Math.sin(f*SIM.getDt())*(this.pose.x-g)+Math.cos(f*SIM.getDt())*(this.pose.y-h)+h;this.pose.theta;this.pose.theta=this.pose.theta+f*SIM.getDt()}var j=Math.sin(this.pose.theta),k=Math.cos(this.pose.theta);this.frontRight=this.translate(j,k,this.frontRight),this.frontLeft=this.translate(j,k,this.frontLeft),this.backRight=this.translate(j,k,this.backRight),this.backLeft=this.translate(j,k,this.backLeft),this.backMiddle=this.translate(j,k,this.backMiddle),this.touchSensor=this.translate(j,k,this.touchSensor),this.colorSensor=this.translate(j,k,this.colorSensor),this.ultraSensor=this.translate(j,k,this.ultraSensor),this.mouse=this.translate(j,k,this.mouse),this.touchSensor.x1=this.frontRight.rx,this.touchSensor.y1=this.frontRight.ry,this.touchSensor.x2=this.frontLeft.rx,this.touchSensor.y2=this.frontLeft.ry},Robot.prototype.translate=function(a,b,c){return c.rx=this.pose.x-c.y*b+c.x*a,c.ry=this.pose.y-c.y*a-c.x*b,c},SimpleRobot.prototype=Object.create(Robot.prototype),SimpleRobot.prototype.constructor=SimpleRobot,RobertaRobot.prototype=Object.create(Robot.prototype),RobertaRobot.prototype.constructor=RobertaRobot,RescueRobot.prototype=Object.create(Robot.prototype),RescueRobot.prototype.constructor=RescueRobot,DrawRobot.prototype=Object.create(Robot.prototype),DrawRobot.prototype.constructor=DrawRobot,DrawRobot.prototype.geom={x:-20,y:-20,w:40,h:40,color:"#FF69B4"},DrawRobot.prototype.touchSensor={x:0,y:-25,x1:0,y1:0,x2:0,y2:0,value:0,color:"#FF69B4"},DrawRobot.prototype.wheelBack={x:-2.5,y:20,w:5,h:5,color:"#999999"},DrawRobot.prototype.led={x:0,y:0,color:"#000000",mode:""},DrawRobot.prototype.frontLeft={x:22.5,y:-25,rx:0,ry:0,bumped:!1},DrawRobot.prototype.frontRight={x:-22.5,y:-25,rx:0,ry:0,bumped:!1},DrawRobot.prototype.backLeft={x:20,y:20,rx:0,ry:0,bumped:!1},DrawRobot.prototype.backRight={x:-20,y:20,rx:0,ry:0,bumped:!1},DrawRobot.prototype.backMiddle={x:0,y:20,rx:0,ry:0},MathRobot.prototype=Object.create(Robot.prototype),MathRobot.prototype.constructor=MathRobot,Scene.prototype.updateBackgrounds=function(){this.drawBackground(1,this.uCtx),this.drawBackground()},Scene.prototype.drawBackground=function(a,b){var c=b||this.bCtx,d=a||SIM.getScale();c.restore(),c.clearRect(0,0,MAX_WIDTH,MAX_HEIGHT),c.save(),c.scale(d,d),this.backgroundImg&&c.drawImage(this.backgroundImg,0,0)},Scene.prototype.drawObjects=function(){this.oCtx.clearRect(this.obstacle.xOld-20,this.obstacle.yOld-20,this.obstacle.wOld+40,this.obstacle.hOld+40),this.obstacle.xOld=this.obstacle.x,this.obstacle.yOld=this.obstacle.y,this.obstacle.wOld=this.obstacle.w,this.obstacle.hOld=this.obstacle.h,this.oCtx.restore(),this.oCtx.save(),this.oCtx.scale(SIM.getScale(),SIM.getScale()),this.obstacle.img?this.oCtx.drawImage(this.obstacle.img,this.obstacle.x,this.obstacle.y,this.obstacle.w,this.obstacle.h):this.obstacle.color&&(this.oCtx.fillStyle=this.obstacle.color,this.oCtx.shadowBlur=5,this.oCtx.shadowColor="black",this.oCtx.fillRect(this.obstacle.x,this.obstacle.y,this.obstacle.w,this.obstacle.h))},Scene.prototype.drawRobot=function(){if(this.rCtx.clearRect(0,0,MAX_WIDTH,MAX_HEIGHT),this.rCtx.restore(),this.rCtx.save(),SIM.getInfo()){var a=this.playground.w-40,b=this.playground.w-5,c=20;this.rCtx.fillStyle="rgba(255,255,255,0.5)",this.rCtx.fillRect(a-80,0,this.playground.w,200),this.rCtx.textAlign="end",this.rCtx.font="10px Verdana";var d,e;5===SIM.getBackground()?(d=(this.robot.pose.x+this.robot.pose.transX)/3,e=(-this.robot.pose.y-this.robot.pose.transY)/3,this.rCtx.fillStyle="#ffffff"):(d=this.robot.pose.x+this.robot.pose.transX,e=+this.robot.pose.y+this.robot.pose.transY,this.rCtx.fillStyle="#333333"),this.rCtx.fillText("FPS",a,c),this.rCtx.fillText(Math.round(1/SIM.getDt()),b,c),c+=15,this.rCtx.fillText("Time",a,c),this.rCtx.fillText(Math.round(10*this.robot.time)/10,b,c),c+=15,this.rCtx.fillText("Robot X",a,c),this.rCtx.fillText(Math.round(d),b,c),c+=15,this.rCtx.fillText("Robot Y",a,c),this.rCtx.fillText(Math.round(e),b,c),c+=15,this.rCtx.fillText("Robot \u03b8",a,c),this.rCtx.fillText(Math.round(Math.round(SIMATH.toDegree(this.robot.pose.theta))),b,c),c+=25,this.rCtx.fillText("Motor left",a,c),this.rCtx.fillText(Math.round(this.robot.encoder.left*ENC),b,c),c+=15,this.rCtx.fillText("Motor right",a,c),this.rCtx.fillText(Math.round(this.robot.encoder.right*ENC),b,c),c+=15,this.rCtx.fillText("Touch Sensor",a,c),this.rCtx.fillText(Math.round(this.robot.touchSensor.value),b,c),c+=15,this.rCtx.fillText("Light Sensor",a,c),this.rCtx.fillText(Math.round(Math.round(this.robot.lightSensor.lightValue)),b,c),c+=15,this.rCtx.fillText("Ultra Sensor",a,c),this.rCtx.fillText(Math.round(this.robot.ultraSensor.distance/3),b,c),c+=15,this.rCtx.fillText("Color Sensor",a,c),this.rCtx.beginPath(),this.rCtx.fillStyle=this.robot.colorSensor.color,this.rCtx.rect(b,c,-10,-10),this.rCtx.stroke(),this.rCtx.fill()}this.rCtx.scale(SIM.getScale(),SIM.getScale()),this.rCtx.save(),this.rCtx.translate(this.robot.pose.x,this.robot.pose.y),this.rCtx.rotate(SIMATH.toRadians(SIMATH.toDegree(this.robot.pose.theta)-90)),this.rCtx.scale(1,-1),this.rCtx.lineWidth="2.5",this.rCtx.strokeStyle=this.robot.wheelLeft.color,this.rCtx.beginPath(),this.rCtx.moveTo(this.robot.geom.x-5,0),this.rCtx.lineTo(this.robot.geom.x+this.robot.geom.w+5,0),this.rCtx.stroke(),this.rCtx.fillStyle=this.robot.wheelBack.color,this.rCtx.fillRect(this.robot.wheelBack.x,this.robot.wheelBack.y,this.robot.wheelBack.w,this.robot.wheelBack.h),this.rCtx.shadowBlur=0,this.rCtx.shadowOffsetX=0,this.rCtx.fillStyle=this.robot.touchSensor.color,this.rCtx.fillRect(this.robot.frontRight.x+12.5,this.robot.frontRight.y,20,10),this.rCtx.fillStyle=this.robot.led.color;var f=this.rCtx.createRadialGradient(this.robot.led.x,this.robot.led.y,1,this.robot.led.x,this.robot.led.y,15);f.addColorStop(0,this.robot.led.color),f.addColorStop(.5,this.robot.geom.color),this.rCtx.shadowBlur=5,this.rCtx.shadowColor="black",this.rCtx.fillStyle=f,this.rCtx.beginPath(),this.rCtx.moveTo(this.robot.geom.x+2.5,this.robot.geom.y),this.rCtx.lineTo(this.robot.geom.x+this.robot.geom.w-2.5,this.robot.geom.y),this.rCtx.quadraticCurveTo(this.robot.geom.x+this.robot.geom.w,this.robot.geom.y,this.robot.geom.x+this.robot.geom.w,this.robot.geom.y+2.5),this.rCtx.lineTo(this.robot.geom.x+this.robot.geom.w,this.robot.geom.y+this.robot.geom.h-2.5),this.rCtx.quadraticCurveTo(this.robot.geom.x+this.robot.geom.w,this.robot.geom.y+this.robot.geom.h,this.robot.geom.x+this.robot.geom.w-2.5,this.robot.geom.y+this.robot.geom.h),this.rCtx.lineTo(this.robot.geom.x+2.5,this.robot.geom.y+this.robot.geom.h),this.rCtx.quadraticCurveTo(this.robot.geom.x,this.robot.geom.y+this.robot.geom.h,this.robot.geom.x,this.robot.geom.y+this.robot.geom.h-2.5),this.rCtx.lineTo(this.robot.geom.x,this.robot.geom.y+2.5),this.rCtx.quadraticCurveTo(this.robot.geom.x,this.robot.geom.y,this.robot.geom.x+2.5,this.robot.geom.y),this.rCtx.closePath(),this.rCtx.fill(),this.rCtx.shadowBlur=5,this.rCtx.shadowOffsetX=2,1===this.robot.touchSensor.value?(this.rCtx.fillStyle="red",this.rCtx.fillRect(this.robot.frontRight.x,this.robot.frontRight.y,this.robot.frontLeft.x-this.robot.frontRight.x,3.5)):(this.rCtx.fillStyle=this.robot.touchSensor.color,this.rCtx.fillRect(this.robot.frontRight.x,this.robot.frontRight.y,this.robot.frontLeft.x-this.robot.frontRight.x,3.5)),this.rCtx.shadowBlur=0,this.rCtx.shadowOffsetX=0,this.rCtx.fillStyle=this.robot.led.color,this.rCtx.beginPath(),this.rCtx.arc(this.robot.led.x,this.robot.led.y,2.5,0,2*Math.PI),this.rCtx.fill(),this.rCtx.fillStyle=this.robot.wheelLeft.color,this.rCtx.fillRect(this.robot.wheelLeft.x,this.robot.wheelLeft.y,this.robot.wheelLeft.w,this.robot.wheelLeft.h),this.rCtx.fillStyle=this.robot.wheelRight.color,this.rCtx.fillRect(this.robot.wheelRight.x,this.robot.wheelRight.y,this.robot.wheelRight.w,this.robot.wheelRight.h),this.rCtx.lineWidth="0.5",this.rCtx.beginPath(),this.rCtx.arc(0,-15,this.robot.colorSensor.r,0,2*Math.PI),this.rCtx.fillStyle=this.robot.colorSensor.color,this.rCtx.fill(),this.rCtx.strokeStyle="black",this.rCtx.stroke(),this.rCtx.restore(),this.wave+=WAVE_LENGTH*SIM.getDt(),this.wave=this.wave%WAVE_LENGTH,this.rCtx.lineDashOffset=WAVE_LENGTH-this.wave,this.rCtx.setLineDash([20,40]),this.rCtx.beginPath(),this.rCtx.lineWidth="0.5",this.rCtx.strokeStyle="#555555";for(var g=0;gc;c+=4)l.indexOf(c)<0&&(h+=k.data[c+0],i+=k.data[c+1],j+=k.data[c+2],j++);var n=k.data.length/4-12,o=h/n,p=i/n,q=j/n;this.robot.colorSensor&&(this.robot.colorSensor.colorValue=SIMATH.getColor(SIMATH.rgbToHsv(o,p,q)),b.color=this.robot.colorSensor.colorValue,this.robot.colorSensor.colorValue===COLOR_ENUM.NONE?this.robot.colorSensor.color="grey":this.robot.colorSensor.colorValue===COLOR_ENUM.BLACK?this.robot.colorSensor.color="black":this.robot.colorSensor.colorValue==COLOR_ENUM.WHITE?this.robot.colorSensor.color="white":this.robot.colorSensor.colorValue===COLOR_ENUM.YELLOW?this.robot.colorSensor.color="yellow":this.robot.colorSensor.colorValue===COLOR_ENUM.BROWN?this.robot.colorSensor.color="brown":this.robot.colorSensor.colorValue===COLOR_ENUM.RED?this.robot.colorSensor.color="red":this.robot.colorSensor.colorValue===COLOR_ENUM.BLUE?this.robot.colorSensor.color="blue":this.robot.colorSensor.colorValue===COLOR_ENUM.GREEN&&(this.robot.colorSensor.color="lime")),this.robot.lightSensor&&(this.robot.lightSensor.lightValue=(o+p+q)/3/2.55,b.light=this.robot.lightSensor.lightValue)}if(this.robot.ultraSensor){var r={x1:this.robot.ultraSensor.rx,y1:this.robot.ultraSensor.ry,x2:this.robot.ultraSensor.rx+MAXDIAG*Math.cos(this.robot.pose.theta),y2:this.robot.ultraSensor.ry+MAXDIAG*Math.sin(this.robot.pose.theta)},s={x1:this.robot.ultraSensor.rx,y1:this.robot.ultraSensor.ry,x2:this.robot.ultraSensor.rx+MAXDIAG*Math.cos(this.robot.pose.theta-Math.PI/8),y2:this.robot.ultraSensor.ry+MAXDIAG*Math.sin(this.robot.pose.theta-Math.PI/8)},t={x1:this.robot.ultraSensor.rx,y1:this.robot.ultraSensor.ry,x2:this.robot.ultraSensor.rx+MAXDIAG*Math.cos(this.robot.pose.theta-Math.PI/16),y2:this.robot.ultraSensor.ry+MAXDIAG*Math.sin(this.robot.pose.theta-Math.PI/16)},u={x1:this.robot.ultraSensor.rx,y1:this.robot.ultraSensor.ry,x2:this.robot.ultraSensor.rx+MAXDIAG*Math.cos(this.robot.pose.theta+Math.PI/8),y2:this.robot.ultraSensor.ry+MAXDIAG*Math.sin(this.robot.pose.theta+Math.PI/8)},v={x1:this.robot.ultraSensor.rx,y1:this.robot.ultraSensor.ry,x2:this.robot.ultraSensor.rx+MAXDIAG*Math.cos(this.robot.pose.theta+Math.PI/16),y2:this.robot.ultraSensor.ry+MAXDIAG*Math.sin(this.robot.pose.theta+Math.PI/16)},w=new Array(s,t,r,v,u);this.robot.ultraSensor.distance=MAXDIAG;for(var c=0;cMath.max(a.x1,a.x2)+.01?null:dMath.max(b.x1,b.x2)+.01?null:eMath.max(a.y1,a.y2)+.01?null:eMath.max(b.y1,b.y2)+.01?null:{x:d,y:e}},SIMATH.getLinesFromRect=function(a){return[{x1:a.x,x2:a.x,y1:a.y,y2:a.y+a.h},{x1:a.x,x2:a.x+a.w,y1:a.y,y2:a.y},{x1:a.x+a.w,x2:a.x,y1:a.y+a.h,y2:a.y+a.h},{x1:a.x+a.w,x2:a.x+a.w,y1:a.y+a.h,y2:a.y}]},SIMATH.sqr=function(a){return a*a},SIMATH.getDistance=function(a,b){return SIMATH.sqr(a.x-b.x)+SIMATH.sqr(a.y-b.y)},SIMATH.getDistanceToLine=function(a,b,c){var d=SIMATH.getDistance(b,c);if(0==d)return b;var e=((a.x-b.x)*(c.x-b.x)+(a.y-b.y)*(c.y-b.y))/d;return 0>e?b:e>1?c:{x:b.x+e*(c.x-b.x),y:b.y+e*(c.y-b.y)}},SIMATH.rgbToHsv=function(a,b,c){var g,h,d=Math.min(a,b,c),e=Math.max(a,b,c),f=e-d,i=e;return i=Math.floor(e/255*100),0===e?[0,0,0]:(h=Math.floor(f/e*100),g=a===e?(b-c)/f:b===e?2+(c-a)/f:4+(a-b)/f,g=Math.floor(60*g),0>g&&(g+=360),[g,h,i])},SIMATH.getColor=function(a){return a[2]<=10?COLOR_ENUM.BLACK:(a[0]<10||a[0]>350)&&a[1]>90&&a[2]>50?COLOR_ENUM.RED:a[0]>40&&a[0]<70&&a[1]>90&&a[2]>50?COLOR_ENUM.YELLOW:a[0]<50&&a[1]>50&&a[1]<100&&a[2]<50?COLOR_ENUM.BROWN:a[1]<10&&a[2]>90?COLOR_ENUM.WHITE:a[0]>70&&a[0]<160&&a[1]>80?COLOR_ENUM.GREEN:a[0]>200&&a[0]<250&&a[1]>90&&a[2]>50?COLOR_ENUM.BLUE:COLOR_ENUM.NONE}}($);var SIM=function(){function setBackground(a){return window.removeEventListener("resize",resizeAll),setPause(!0),0===a?(currentBackground+=1,currentBackground>5&&(currentBackground=1)):currentBackground=a,1==currentBackground?robot=new SimpleRobot:2==currentBackground?robot=new DrawRobot:3==currentBackground?robot=new RobertaRobot:4==currentBackground?robot=new RescueRobot:5==currentBackground&&(robot=new MathRobot),setObstacle(),scene=new Scene(img[currentBackground],layers,robot,obstacle),resizeAll(),scene.updateBackgrounds(),scene.drawObjects(),reloadProgram(),window.addEventListener("resize",resizeAll),currentBackground}function getBackground(){return currentBackground}function getDt(){return dt}function setPause(a){a||ready?(a?($(".simForward").removeClass("typcn-media-pause"),$(".simForward").addClass("typcn-media-play")):($(".simForward").removeClass("typcn-media-play"),$(".simForward").addClass("typcn-media-pause")),pause=a):setTimeout(function(){setPause(!1)},100)}function setStep(){stepCounter=-50,setPause(!1)}function setInfo(){info=info===!0?!1:!0}function stopProgram(){setPause(!0),robot.reset(),scene.updateBackgrounds(),reloadProgram()}function init(program){ready=!1,userProgram=program,eval(userProgram),canceled=!1,isDownrobot=!1,isDownObstacle=!1,stepCounter=0,pause=!0,info=!1,robot.reset(),img=[],loadImages(0)}function cancel(){$(window).off("resize"),canceled=!0,removeMouseEvents(),destroyLayers()}function render(){if(canceled)return void cancelAnimationFrame(globalID);globalID=requestAnimationFrame(render);var now=(new Date).getTime();dt=now-(time||now),dt/=1e3,time=now,stepCounter+=1,output.left=0,output.right=0,PROGRAM_SIMULATION.isTerminated()||pause?PROGRAM_SIMULATION.isTerminated()&&(reloadProgram(),eval(userProgram),$(".simForward").removeClass("typcn-media-pause"),$(".simForward").addClass("typcn-media-play"),setPause(!0)):(0===stepCounter&&setPause(!0),step(input),setOutput()),robot.updatePose(output),input=scene.updateSensorValues(!pause),scene.drawRobot()}function reloadProgram(){eval(userProgram),$(".simForward").removeClass("typcn-media-pause"),$(".simForward").addClass("typcn-media-play")}function setOutput(){output.left=ACTORS.getLeftMotor().getPower()*MAXPOWER||0,output.right=ACTORS.getRightMotor().getPower()*MAXPOWER||0,robot.led.mode=output.ledMode=LIGHT.getMode()||"OFF",LIGHT.getMode()&&"OFF"==LIGHT.getMode()?robot.led.color=output.led="#dddddd":robot.led.color=output.led=LIGHT.getColor()}function setObstacle(){2==currentBackground?(obstacle.x=500,obstacle.y=250,obstacle.w=100,obstacle.h=100,obstacle.img=null,obstacle.color="#33B8CA"):1==currentBackground?(obstacle.x=580,obstacle.y=290,obstacle.w=100,obstacle.h=100,obstacle.img=null,obstacle.color="#33B8CA"):3==currentBackground?(obstacle.x=500,obstacle.y=250,obstacle.w=100,obstacle.h=100,obstacle.img=img[0],obstacle.color=null):5==currentBackground?(obstacle.x=0,obstacle.y=0,obstacle.w=0,obstacle.h=0,obstacle.color=null):(obstacle.x=495,obstacle.y=396,obstacle.w=20,obstacle.h=20,obstacle.color="#33B8CA",obstacle.img=null)}function handleMouseDown(a){a.preventDefault();var b=a.clientX||a.originalEvent.touches[0].pageX,c=a.clientY||a.originalEvent.touches[0].pageY;startX=parseInt(b-offsetX,10)/scale,startY=parseInt(c-offsetY,10)/scale;var d=startX-robot.mouse.rx,e=startY-robot.mouse.ry;isDownrobot=d*d+e*eobstacle.x&&startXobstacle.y&&startY=1920&&(scale=1.5),ground.w=scene.playground.w/scale,ground.h=scene.playground.h/scale,a!=scale&&(scene.updateBackgrounds(),scene.drawObjects())}}function loadImages(a){a