Skip to content
Snippets Groups Projects
Commit 151fe395 authored by Anian Bühler's avatar Anian Bühler
Browse files

added PID-block

parent a617b9ae
No related branches found
No related tags found
1 merge request!1dev_prefereences to master
...@@ -8,10 +8,6 @@ import com.ardublock.translator.block.exception.BlockException; ...@@ -8,10 +8,6 @@ import com.ardublock.translator.block.exception.BlockException;
import com.ardublock.translator.block.exception.SocketNullException; import com.ardublock.translator.block.exception.SocketNullException;
import com.ardublock.translator.block.exception.SubroutineNotDeclaredException; import com.ardublock.translator.block.exception.SubroutineNotDeclaredException;
import tec.letsgoing.ardublock.simulator.simcode.SimCode;
import tec.letsgoing.ardublock.simulator.simcode.datatypes.SimTypeBool;
import tec.letsgoing.ardublock.simulator.simcode.datatypes.SimTypeString;
import tec.letsgoing.ardublock.simulator.simcode.vars.CodeBoolSet;
public class DefineBlock extends TranslatorBlock public class DefineBlock extends TranslatorBlock
{ {
...@@ -25,7 +21,7 @@ public class DefineBlock extends TranslatorBlock ...@@ -25,7 +21,7 @@ public class DefineBlock extends TranslatorBlock
public String toCode() throws SocketNullException, SubroutineNotDeclaredException public String toCode() throws SocketNullException, SubroutineNotDeclaredException
{ {
//Label autoText set in edu.mit.blocks.renderable.BlockLabel -> generateLabelText() //Label autoText set in edu.mit.blocks.renderable.BlockLabel -> generateLabelText()
String suffix = ""; //String suffix = "";
String newMarker = "_.new"; String newMarker = "_.new";
String regex = "\\s*"+newMarker+"\\b\\s*"; String regex = "\\s*"+newMarker+"\\b\\s*";
... ...
......
package com.ardublock.translator.block.operators;
import java.util.ResourceBundle;
import java.util.function.ToIntFunction;
import com.ardublock.translator.Translator;
import com.ardublock.translator.block.TranslatorBlock;
import com.ardublock.translator.block.exception.BlockException;
import com.ardublock.translator.block.exception.SocketNullException;
import com.ardublock.translator.block.exception.SubroutineNotDeclaredException;
public class PidBlock extends TranslatorBlock
{
private static ResourceBundle uiMessageBundle = ResourceBundle.getBundle("com/ardublock/block/ardublock");
public PidBlock(Long blockId, Translator translator, String codePrefix, String codeSuffix, String label)
{
super(blockId, translator, codePrefix, codeSuffix, label);
}
@Override
public String toCode() throws SocketNullException, SubroutineNotDeclaredException
{
TranslatorBlock tb_input = this.getRequiredTranslatorBlockAtSocket(0);
TranslatorBlock tb_setpoint = this.getRequiredTranslatorBlockAtSocket(1);
TranslatorBlock tb_interval = this.getRequiredTranslatorBlockAtSocket(2);
TranslatorBlock tb_kp = this.getRequiredTranslatorBlockAtSocket(3);
TranslatorBlock tb_ki = this.getTranslatorBlockAtSocket(4);
TranslatorBlock tb_kd = this.getTranslatorBlockAtSocket(5);
TranslatorBlock tb_limitL = this.getTranslatorBlockAtSocket(6);
TranslatorBlock tb_limitH = this.getTranslatorBlockAtSocket(7);
boolean integrative = tb_ki != null;
boolean derivative = tb_kd != null;
boolean limited = (tb_limitL != null) && (tb_limitH != null);
//FUNCTION CODE ASSEMBLY
String functionCode = "int computePID(int input, int setpoint, long interval, int kp";
if(integrative) {
functionCode +=", double ki";
}
if(derivative) {
functionCode +=", double kd";
}
if(limited) {
functionCode +=", int limitLow, int limitHigh";
}
functionCode += "){"
+ " static int lastError = 0;\n"
+ " static int out = 0;\n"
+ " static long lastTime = 0L;\n\n"
+ " long currentTime = millis();\t//get current time\n\n"
+ " if (currentTime >= lastTime + interval) {\n"
+ " long elapsedTime = (double)(currentTime - lastTime); //compute time elapsed from previous computation\n"
+ " \n"
+ " long error = setpoint - input; // get error\n"
+ " out = kp * error; //P output\n\n";
if(integrative) {
functionCode +=" long cumError = cumError + error * elapsedTime; // compute integral\n"
+ " out = out + ki * cumError; //I output\n\n";
}
if(derivative) {
functionCode +=" long rateError = (error - lastError) / elapsedTime; // compute derivative\n"
+ " out = out + kd * rateError; //D output\n\n";
}
if(limited) {
functionCode +=" out = constrain(out, limitLow, limitHigh); //limit output\n\n";
}
functionCode += " lastError = error; //remember current error\n"
+ " lastTime = currentTime; //remember current time\n"
+ " }\n"
+ " return out; //return the PID output\n"
+ "}";
translator.addDefinitionCommand(functionCode);
//RETURN (BLOCK) CODE ASSEMBLY
String ret = "computePID(";
ret += tb_input.toCode().replaceAll("\\s*_.new\\b\\s*", "")+", "+tb_setpoint.toCode().replaceAll("\\s*_.new\\b\\s*", "") + ", " + tb_interval.toCode().replaceAll("\\s*_.new\\b\\s*", "") + ", " + tb_kp.toCode().replaceAll("\\s*_.new\\b\\s*", "");
if(integrative) {
ret +=", " + tb_ki.toCode().replaceAll("\\s*_.new\\b\\s*", "");
}
if(derivative) {
ret +=", " + tb_kd.toCode().replaceAll("\\s*_.new\\b\\s*", "");
}
if(limited) {
String limitL = tb_limitL.toCode().replaceAll("\\s*_.new\\b\\s*", "");
String limitH = tb_limitH.toCode().replaceAll("\\s*_.new\\b\\s*", "");
if(Integer.parseInt(limitL) < Integer.parseInt(limitH)) {
ret +=", " + limitL + ", " + limitH;
}else {
throw new BlockException(blockId, uiMessageBundle.getString("ardublock.error_msg.pid_limit_error"));
}
}
ret += ")";
return codePrefix + ret + codeSuffix;
}
}
...@@ -118,6 +118,7 @@ ardublock.error_msg.stepper_duplicated=There is already a stepper with this name ...@@ -118,6 +118,7 @@ ardublock.error_msg.stepper_duplicated=There is already a stepper with this name
ardublock.error_msg.stepper_not_existing=There is no stepper with this name ardublock.error_msg.stepper_not_existing=There is no stepper with this name
ardublock.error_msg.paste.invalid=clipboard contains no blocks ardublock.error_msg.paste.invalid=clipboard contains no blocks
ardublock.error_msg.paste.notpossible=Past not possible without Blocks ardublock.error_msg.paste.notpossible=Past not possible without Blocks
ardublock.error_msg.pid_limit_error=PID-Block: Upper limit is smaller or equal to lower limit
ardublock.error_msg.no_sim_for_block=This Block is not suitable for simulation ardublock.error_msg.no_sim_for_block=This Block is not suitable for simulation
...@@ -490,6 +491,7 @@ bd.operators=Math Operators ...@@ -490,6 +491,7 @@ bd.operators=Math Operators
bg.mathDivider1=| operators | bg.mathDivider1=| operators |
bg.mathDivider2=| signal attributes | bg.mathDivider2=| signal attributes |
bg.mathDivider3=| random | bg.mathDivider3=| random |
bg.mathDivider4=| PID-Controller |
bg.constrain=constrain bg.constrain=constrain
bg.abs=abs bg.abs=abs
...@@ -537,6 +539,20 @@ bc.low=lower ...@@ -537,6 +539,20 @@ bc.low=lower
bc.high=higher bc.high=higher
bc.element = element bc.element = element
bg.pid=PID
bg.pid_limit=PID
bg.pid.description= PID controller block
bg.pid_limit.description= PID controller block with limit
bc.input=input
bc.setpoint=setpoint
bc.interval=interval
bc.kp=Kp
bc.ki=Ki
bc.kd=Kd
bc.limitL=lower limit
bc.limitH=upper limit
#CAST #CAST
#**************************** #****************************
bd.cast=type cast bd.cast=type cast
... ...
......
...@@ -1257,6 +1257,7 @@ ...@@ -1257,6 +1257,7 @@
<BlockGenus name="mathDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider1" color="150 150 150" /> <BlockGenus name="mathDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider1" color="150 150 150" />
<BlockGenus name="mathDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider2" color="150 150 150" /> <BlockGenus name="mathDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider2" color="150 150 150" />
<BlockGenus name="mathDivider3" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider3" color="150 150 150" /> <BlockGenus name="mathDivider3" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider3" color="150 150 150" />
<BlockGenus name="mathDivider4" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider3" color="150 150 150" />
<BlockGenus name="addition" kind="function" initlabel="bg.addition" color="160 32 240"> <BlockGenus name="addition" kind="function" initlabel="bg.addition" color="160 32 240">
<description> <description>
...@@ -1473,6 +1474,56 @@ ...@@ -1473,6 +1474,56 @@
</BlockConnectors> </BlockConnectors>
</BlockGenus> </BlockGenus>
<BlockGenus name="pid" kind="function" color="160 32 240" initlabel="bg.pid">
<description>
<text>PID</text>
</description>
<BlockConnectors>
<BlockConnector connector-type="number" connector-kind="plug" />
<BlockConnector connector-type="number" connector-kind="socket" label="bc.input" />
<BlockConnector connector-type="number" connector-kind="socket" label="bc.setpoint">
<DefaultArg genus-name="number" label="512" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.interval">
<DefaultArg genus-name="number" label="100" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.kp">
<DefaultArg genus-name="number" label="2" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.ki">
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.kd">
</BlockConnector>
</BlockConnectors>
</BlockGenus>
<BlockGenus name="pid_limit" kind="function" color="160 32 240" initlabel="bg.pid_limit">
<description>
<text>PID with limits</text>
</description>
<BlockConnectors>
<BlockConnector connector-type="number" connector-kind="plug" />
<BlockConnector connector-type="number" connector-kind="socket" label="bc.input" />
<BlockConnector connector-type="number" connector-kind="socket" label="bc.setpoint">
<DefaultArg genus-name="number" label="512" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.interval">
<DefaultArg genus-name="number" label="100" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.kp">
<DefaultArg genus-name="number" label="2" />
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.ki">
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.kd">
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.limitL">
</BlockConnector>
<BlockConnector connector-type="number" connector-kind="socket" label="bc.limitH">
</BlockConnector>
</BlockConnectors>
</BlockGenus>
<!-- ******************** Cast *************** --> <!-- ******************** Cast *************** -->
<BlockGenus name="castDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider1" color="150 150 150" /> <BlockGenus name="castDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider1" color="150 150 150" />
<BlockGenus name="castDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider2" color="150 150 150" /> <BlockGenus name="castDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider2" color="150 150 150" />
...@@ -3134,6 +3185,10 @@ ...@@ -3134,6 +3185,10 @@
<BlockGenusMember>mathDivider3</BlockGenusMember> <BlockGenusMember>mathDivider3</BlockGenusMember>
<BlockGenusMember>random</BlockGenusMember> <BlockGenusMember>random</BlockGenusMember>
<BlockGenusMember>random_range</BlockGenusMember> <BlockGenusMember>random_range</BlockGenusMember>
<BlockGenusMember>mathDivider4</BlockGenusMember>
<BlockGenusMember>pid</BlockGenusMember>
<BlockGenusMember>pid_limit</BlockGenusMember>
</BlockDrawer> </BlockDrawer>
<BlockDrawer button-color="160 32 240" name="bd.operators" type="page"> <BlockDrawer button-color="160 32 240" name="bd.operators" type="page">
<BlockGenusMember>mathDivider1</BlockGenusMember> <BlockGenusMember>mathDivider1</BlockGenusMember>
... ...
......
...@@ -121,6 +121,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen ...@@ -121,6 +121,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen
ardublock.error_msg.paste.invalid=Zwischenablage enthlt keine ArduBlock-Blcke ardublock.error_msg.paste.invalid=Zwischenablage enthlt keine ArduBlock-Blcke
ardublock.error_msg.paste.notpossible=Einfgen ohne Blcke nicht mglich. ardublock.error_msg.paste.notpossible=Einfgen ohne Blcke nicht mglich.
ardublock.error_msg.pid_limit_error=PID-Block: Oberes Limit ist kleiner oder gleich wie unteres Limit
ardublock.error_msg.no_sim_for_block=Dieser Block ist fr die Simulation nicht geeignet. ardublock.error_msg.no_sim_for_block=Dieser Block ist fr die Simulation nicht geeignet.
#TRANSLATOR #TRANSLATOR
...@@ -487,6 +489,7 @@ bd.operators=Math. Operatoren ...@@ -487,6 +489,7 @@ bd.operators=Math. Operatoren
bg.mathDivider1=| Operatoren | bg.mathDivider1=| Operatoren |
bg.mathDivider2=| Signalanpassung | bg.mathDivider2=| Signalanpassung |
bg.mathDivider3=| Zufallszahl | bg.mathDivider3=| Zufallszahl |
bg.mathDivider4=| PID-Regler |
bg.constrain=einschrnken bg.constrain=einschrnken
bg.abs=abs bg.abs=abs
...@@ -534,6 +537,22 @@ bc.low=unterer ...@@ -534,6 +537,22 @@ bc.low=unterer
bc.high=oberer bc.high=oberer
bc.element = Element bc.element = Element
bg.pid=PID
bg.pid_limit=PID
bg.pid.description= PID Regler-Block
bg.pid_limit.description= PID Regler-Block mit Begrenzung
bc.input=Istwert
bc.setpoint=Sollwert
bc.interval=Intervall
bc.kp=Kp
bc.ki=Ki
bc.kd=Kd
bc.limitL=unteres Limit
bc.limitH=oberes Limit
#CAST #CAST
#**************************** #****************************
bd.cast=Typ Konvertierung bd.cast=Typ Konvertierung
... ...
......
...@@ -122,6 +122,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen ...@@ -122,6 +122,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen
ardublock.error_msg.paste.invalid=Zwischenablage enthlt keine ArduBlock-Blcke ardublock.error_msg.paste.invalid=Zwischenablage enthlt keine ArduBlock-Blcke
ardublock.error_msg.paste.notpossible=Einfgen ohne Blcke nicht mglich. ardublock.error_msg.paste.notpossible=Einfgen ohne Blcke nicht mglich.
ardublock.error_msg.pid_limit_error=PID-Block: Oberes Limit ist kleiner oder gleich wie unteres Limit
ardublock.error_msg.no_sim_for_block=Dieser Block ist fr die Simulation nicht geeignet. ardublock.error_msg.no_sim_for_block=Dieser Block ist fr die Simulation nicht geeignet.
#TRANSLATOR #TRANSLATOR
...@@ -488,6 +490,7 @@ bd.operators=Math. Operatoren ...@@ -488,6 +490,7 @@ bd.operators=Math. Operatoren
bg.mathDivider1=| Operatoren | bg.mathDivider1=| Operatoren |
bg.mathDivider2=| Signalanpassung | bg.mathDivider2=| Signalanpassung |
bg.mathDivider3=| Zufallszahl | bg.mathDivider3=| Zufallszahl |
bg.mathDivider4=| PID-Regler |
bg.constrain=constrain bg.constrain=constrain
bg.abs=abs bg.abs=abs
...@@ -535,6 +538,20 @@ bc.low=unterer ...@@ -535,6 +538,20 @@ bc.low=unterer
bc.high=oberer bc.high=oberer
bc.element = Element bc.element = Element
bg.pid=PID
bg.pid_limit=PID
bg.pid.description= PID Regler-Block
bg.pid_limit.description= PID Regler-Block mit Begrenzung
bc.input=Istwert
bc.setpoint=Sollwert
bc.interval=Intervall
bc.kp=Kp
bc.ki=Ki
bc.kd=Kd
bc.limitL=unteres Limit
bc.limitH=oberes Limit
#CAST #CAST
#**************************** #****************************
bd.cast=Typ Konvertierung bd.cast=Typ Konvertierung
... ...
......
...@@ -167,6 +167,9 @@ random_range=com.ardublock.translator.block.operators.RandomRangeBlock ...@@ -167,6 +167,9 @@ random_range=com.ardublock.translator.block.operators.RandomRangeBlock
map_common=com.ardublock.translator.block.operators.MapCommonBlock map_common=com.ardublock.translator.block.operators.MapCommonBlock
map=com.ardublock.translator.block.operators.MapBlock map=com.ardublock.translator.block.operators.MapBlock
pid=com.ardublock.translator.block.operators.PidBlock
pid_limit=com.ardublock.translator.block.operators.PidBlock
#CAST #CAST
#**************************** #****************************
cast_atoi=com.ardublock.translator.block.cast.CastAtoi cast_atoi=com.ardublock.translator.block.cast.CastAtoi
... ...
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment