0% found this document useful (0 votes)
16 views81 pages

21BPS1034 Lab-9

This document describes running six examples using the Ptolemy software to analyze and evaluate the impact of modifying parameters in an electric power generator system. It provides instructions on installing and familiarizing with Ptolemy, identifying a system to analyze, selecting and modifying parameters, observing the resulting time plots, analyzing observed changes, and documenting results.

Uploaded by

divyendu05052003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views81 pages

21BPS1034 Lab-9

This document describes running six examples using the Ptolemy software to analyze and evaluate the impact of modifying parameters in an electric power generator system. It provides instructions on installing and familiarizing with Ptolemy, identifying a system to analyze, selecting and modifying parameters, observing the resulting time plots, analyzing observed changes, and documenting results.

Uploaded by

divyendu05052003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 81

VELLORE INSTITUTE OF TECHNOLOGY

CHENNAI CAMPUS

PROGRAMME: BTECH CSE WITH SPECIALIZATION IN


CPS

BCSE429P- Cyber Physical System Design Lab

Lab 9

PTOELMY INSTALLATION AND RUNNING


SIX EXAMPLES

Name: DIVYENDU VIMAL


Registration No: 21BPS1487
Faculty coordinator: Dr. Priyadarshini
R Slot: L7+L8
ELECTRIC POWER SYSTEM

AIM:

To analyze and evaluate the impact of Electric Power Generator System by


modifying system parameters on time-plots within the Ptolemy software
environment. This involves systematically observing and documenting the changes in
the time-plots' characteristics as a result of editing various parameters. The goal is to
gain insights into the system's behavior under different configurations, which can be
useful for optimizing performance and enhancing overall understanding of the
software's functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The Electric Power Generator System to be analyzed along with its associated
time- plots should be identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:

STRUCTURE OF ACTORS USED:


OUTPUT SCREENSHOT:
SOURCE CODE:
package ptolemy.actor.lib;

import java.util.HashMap;
import java.util.Iterator;
import
java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import ptolemy.actor.IOPort;
import
ptolemy.actor.TypedAtomicActor;
import ptolemy.actor.TypedIOPort;
import ptolemy.data.DoubleToken;
import ptolemy.data.IntToken;
import ptolemy.data.Token;
import
ptolemy.data.expr.ASTPtRootNode;
import ptolemy.data.expr.ModelScope;
import ptolemy.data.expr.Parameter;
import ptolemy.data.expr.ParseTreeEvaluator;
import
ptolemy.data.expr.ParseTreeFreeVariableCollector;
import ptolemy.data.expr.ParseTreeTypeInference;
import ptolemy.data.expr.PtParser;
import ptolemy.data.expr.Variable;
import
ptolemy.data.type.BaseType;
import
ptolemy.data.type.MonotonicFunction;
import ptolemy.data.type.Type;
import ptolemy.data.type.TypeConstant;
import ptolemy.graph.InequalityTerm;
import
ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Settable;
import
ptolemy.kernel.util.StringAttribute;
import ptolemy.kernel.util.Workspace;

public class Expression extends TypedAtomicActor {tor with this name.


*/
public Expression(CompositeEntity container, String name)
throws NameDuplicationException, IllegalActionException
{
super(container, name);
output = new TypedIOPort(this, "output", false,
true); expression = new StringAttribute(this,
"expression"); expression.setExpression("");
Parameter hide = new Parameter(expression,
"_hide"); hide.setExpression("true");
hide.setVisibility(Settable.NONE);

_setOutputTypeConstraint();
}
public TypedIOPort output;
public StringAttribute
expression; @Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == expression) {
_parseTree = null;
}
}
@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ Expression newObject = (Expression) super.clone(workspace);
newObject._iterationCount = 1;
newObject._parseTree = null;
newObject._parseTreeEvaluator = null;
newObject._scope = null;
newObject._setOutputTypeConstraint()
; newObject._tokenMap = null;
return newObject;
}
@Override
public void fire() throws IllegalActionException
{ super.fire();
Iterator inputPorts = inputPortList().iterator();

while (inputPorts.hasNext()) {
IOPort port = (IOPort) inputPorts.next();

// FIXME: Handle multiports


if (port.isOutsideConnected())
{ if (port.hasToken(0)) {
Token inputToken = port.get(0);
_tokenMap.put(port.getName(), inputToken);
} else {
throw new IllegalActionException(this,
"Input port " + port.getName() + " has no data.");
}
}
}

try {,
if (_parseTree == null) {
PtParser parser = new PtParser();
_parseTree = parser
.generateParseTree(expression.getExpression());
}

if (_parseTreeEvaluator == null) {
_parseTreeEvaluator = new ParseTreeEvaluator();
}

if (_scope == null) {
_scope = new VariableScope();
}

_result = _parseTreeEvaluator.evaluateParseTree(_parseTree, _scope);


} catch (Throwable throwable) {
throw new IllegalActionException(this,
throwable, "Expression invalid.");
}

if (_result == null) {
throw new
IllegalActionException(this,
"Expression yields a null result: "
+ expression.getExpression());
}

output.send(0, _result);
}
@Override
public void initialize() throws IllegalActionException
{ super.initialize();
if (getPort("time") != null) {
throw new IllegalActionException(this,
"This actor has a port named \"time\", "
+ "which will not be read, instead the "
+ "reserved system variable \"time\" will be read. "
+ "Delete the \"time\" port to avoid this message.");
}
if (getPort("iteration") != null) {
throw new IllegalActionException(this,
"This actor has a port named \"iteration\", "
+ "which will not be read, instead the "
+ "reserved system variable \"iteration\" will be read. "
+ "Delete the \"iteration\" port to avoid this message.");
}
_iterationCount = 1;
}

@Override
public boolean postfire() throws IllegalActionException {
_iterationCount++;
return
super.postfire();
}
@Override
public boolean prefire() throws IllegalActionException
{ Iterator inputPorts = inputPortList().iterator();

while (inputPorts.hasNext()) {
IOPort port = (IOPort)
inputPorts.next(); if
(port.isOutsideConnected()) {
if (!port.hasToken(0))
{ return false;
}
}
}

return super.prefire();
}
@Override
public void preinitialize() throws IllegalActionException
{ super.preinitialize();
_tokenMap = new HashMap<String, Token>();
}
protected Token _result;

protected Map<String, Token>

_tokenMap; private void

_setOutputTypeConstraint() {
output.setTypeAtLeast(new OutputTypeFunction());
}

private class VariableScope extends ModelScope


{ @Override
public Token get(String name) throws IllegalActionException
{ if (name.equals("time")) {
return new DoubleToken(
getDirector().getModelTime().getDoubleValue());
} else if (name.equals("iteration")) {
return new IntToken(_iterationCount);
}

Token token =

_tokenMap.get(name); if (token !=

null) {
return token;
}

Variable result = getScopedVariable(null, Expression.this,

name); if (result != null) {


return result.getToken();
}

return null;
}
@Override
public Type getType(String name) throws IllegalActionException
{ if (name.equals("time")) {
return BaseType.DOUBLE;
} else if (name.equals("iteration"))
{ return BaseType.INT;
}
TypedIOPort port = (TypedIOPort) getPort(name);

if (port != null) {
return port.getType();
}

Variable result = getScopedVariable(null, Expression.this,

name); if (result != null) {


return (Type) result.getTypeTerm().getValue();
}

return null;
}
@Override
public ptolemy.graph.InequalityTerm getTypeTerm(String
name) throws IllegalActionException {
if (name.equals("time")) {
return new TypeConstant(BaseType.DOUBLE);
} else if (name.equals("iteration")) {
return new TypeConstant(BaseType.INT);
}

TypedIOPort port = (TypedIOPort)

getPort(name); if (port != null) {


return port.getTypeTerm();
}

Variable result = getScopedVariable(null, Expression.this,

name); if (result != null) {


return result.getTypeTerm();
}

return null;
}

@Override
public Set identifierSet() {
return getAllScopedVariableNames(null, Expression.this);
}
}
private class OutputTypeFunction extends MonotonicFunction
{ @Override
public Object getValue() throws IllegalActionException
{ try {
InequalityTerm[] terms = getVariables();

for (InequalityTerm term : terms) {


if (term != this && term.getValue() == BaseType.UNKNOWN)
{ return BaseType.UNKNOWN;
}
}
if (_parseTree == null) {
PtParser parser = new PtParser();
_parseTree = parser
.generateParseTree(expression.getExpression());
}

if (_scope == null) {
_scope = new VariableScope();
}
Type type = _typeInference.inferTypes(_parseTree,
_scope); return type;
} catch (Exception ex) {
throw new IllegalActionException(Expression.this, ex,
"An error occurred during expression type inference of \""
+ expression.getExpression() + "\".");
}
}
@Override
public InequalityTerm[] getVariables()
{ try {
if (_parseTree == null) {
PtParser parser = new PtParser();
_parseTree = parser
.generateParseTree(expression.getExpression());
}

if (_scope == null) {
_scope = new VariableScope();
}

Set set = _variableCollector.collectFreeVariables(_parseTree,


_scope);
List termList = new LinkedList();

for (Iterator elements = set.iterator(); elements.hasNext();)


{ String name = (String) elements.next();
InequalityTerm term = _scope.getTypeTerm(name);

if (term != null && term.isSettable())


{ termList.add(term);
}
}

return (InequalityTerm[]) termList


.toArray(new InequalityTerm[termList.size()]);
} catch (IllegalActionException ex)
{ return new InequalityTerm[0];
}
}
@Override
public String getVerboseString() {
return expression.getExpression();
}
private ParseTreeTypeInference _typeInference = new ParseTreeTypeInference();

private ParseTreeFreeVariableCollector _variableCollector =


new ParseTreeFreeVariableCollector();
}

private int _iterationCount = 1;

private ASTPtRootNode _parseTree = null;

private ParseTreeEvaluator _parseTreeEvaluator = null;

private VariableScope _scope = null;


}

public class TimedPlotter extends Plotter implements TimedActor


{ public TimedPlotter(CompositeEntity container, String name)
throws IllegalActionException, NameDuplicationException
{ super(container, name);
disconnectGraphOnAbsentValue = new Parameter(this,
"disconnectGraphOnAbsentValue", new BooleanToken(false));
disconnectGraphOnAbsentValue.setTypeEquals(BaseType.BOOLEAN);
input = new TypedIOPort(this, "input", true, false);
input.setMultiport(true);
input.setTypeEquals(BaseType.DOUBLE);

useLocalTime = new Parameter(this,


"useLocalTime");
useLocalTime.setTypeEquals(BaseType.BOOLEAN);
useLocalTime.setExpression("false");
}
public Parameter

disconnectGraphOnAbsentValue; public

Parameter useLocalTime;

@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ TimedPlotter newObject = (TimedPlotter) super.clone(workspace);
newObject._connected = new ArrayList<Boolean>();
return newObject;
}

@Override
public boolean prefire() throws IllegalActionException
{ super.prefire();
int width = input.getWidth();
if (width != _connected.size()) {
_connected.clear();
for (int i = 0; i < width; i++) {
_connected.add(true);
}
}
return true;
}

@Override
public void initialize() throws IllegalActionException
{ super.initialize();
int width = input.getWidth();
_connected.clear();
for (int i = 0; i < width; i++) {
_connected.add(true);
}
((PlotInterface) plot).markDisconnections(true);
}
@Override
public boolean postfire() throws IllegalActionException
{ double currentTimeValue;
int width = input.getWidth();

boolean disconnectOnAbsent = ((BooleanToken) disconnectGraphOnAbsentValue


.getToken()).booleanValue();
int offset = ((IntToken)
startingDataset.getToken()).intValue(); PlotInterface plot =
(PlotInterface) this.plot;
for (int i = width - 1; i >= 0; i--)
{ if (input.hasToken(i)) {
boolean localTime = ((BooleanToken) useLocalTime.getToken())
.booleanValue()
; if (localTime) {
currentTimeValue = input.getModelTime(i).getDoubleValue();
} else {
currentTimeValue = getDirector().getGlobalTime()
.getDoubleValue();
}

DoubleToken currentToken = (DoubleToken) input.get(i);


SmoothToken smoothToken = currentToken instanceof SmoothToken
? (SmoothToken) currentToken
: null;
double[] derivatives;
if (smoothToken != null) {
derivatives =
smoothToken.derivativeValues(); if
(derivatives == null) {
derivatives = new double[0];
}
} else {
derivatives = null;
}
plot.addPoint(i + offset, currentTimeValue,
currentToken.doubleValue(), derivatives,
_connected.get(i));
if (disconnectOnAbsent) {
_connected.set(i, true);
}
} else if (disconnectOnAbsent) {
_connected.set(i, false);
}
}

return super.postfire();
}

private ArrayList<Boolean> _connected = new ArrayList<Boolean>();


}

RESULT:

In Ptolemy, when analyzing a Electric Power Generator System, the results may vary
depending on the edited parameters. Key observations include changes in output
power, efficiency, and stability of the system. By adjusting parameters such as input
power, load demand, or control mechanisms, one can observe how these factors
influence the overall performance of the power generator. The results can provide
valuable insights for improving system efficiency, maintaining optimal performance,
and ensuring the stability of the power generation process.
ROBOT MPC SYSTEM

AIM:

To analyze and evaluate the impact of Robot MPC System by modifying system
parameters on time-plots within the Ptolemy software environment. This involves
systematically observing and documenting the changes in the time-plots'
characteristics as a result of editing various parameters. The goal is to gain
insights into the system's behavior under different configurations, which can be
useful for optimizing performance and enhancing overall understanding of the
software's functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The Robot MPC system to be analyzed along with its associated time-plots should
be identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:

STRUCTURE OF ACTORS USED:


OUTPUT SCREENSHOTS:
SOURCE CODE:
package org.ptolemy.ssm;

import
ptolemy.actor.TypedAtomicActor;
import ptolemy.actor.TypedIOPort;
import ptolemy.data.ArrayToken;
import
ptolemy.data.DoubleMatrixToken;
import ptolemy.data.DoubleToken;
import ptolemy.data.IntToken;
import ptolemy.data.RecordToken;
import ptolemy.data.StringToken;
import ptolemy.data.expr.Parameter;
import ptolemy.data.type.ArrayType;
import ptolemy.data.type.BaseType;
import
ptolemy.data.type.RecordType;
import ptolemy.data.type.Type;
import
ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.math.DoubleMatrixMath;

public class StatePredictorWithControl extends TypedAtomicActor {


public StatePredictorWithControl(CompositeEntity container, String
name) throws NameDuplicationException, IllegalActionException {
super(container, name);
controlInput = new TypedIOPort(this, "control_input", true,
false); controlInput
.setTypeEquals(new ArrayType(new ArrayType(BaseType.DOUBLE)));

currentState = new TypedIOPort(this, "current_state", true,


false); ArrayToken names = new ArrayToken("{\"x\",\"y\"}");
String stateName;
_labels = new String[names.length()];
_types = new Type[names.length()];
for (int i = 0; i < names.length(); i++)
{
stateName = ((StringToken) names.getElement(i)).stringValue();
_labels[i] = stateName;
_types[i] = BaseType.DOUBLE;
}
currentState.setTypeEquals(new RecordType(_labels, _types));
predictedStates = new TypedIOPort(this, "predicted_states", false,
true);
predictedStates
.setTypeEquals(new ArrayType(new RecordType(_labels, _types)));

jacobianOfStates = new TypedIOPort(this, "jacobianOfStates",


false, true);
jacobianOfStates.setTypeEquals(new ArrayType(BaseType.DOUBLE_MATRIX));

_timeHorizon = 1;
timeHorizon = new Parameter(this, "prediction
horizon"); timeHorizon.setExpression("1");
timeHorizon.setTypeEquals(BaseType.INT);
}
public Parameter timeHorizon;
public TypedIOPort controlInput;
public TypedIOPort currentState;
public TypedIOPort predictedStates;
public TypedIOPort
jacobianOfStates; @Override
public void fire() throws IllegalActionException {

super.fire();
if (controlInput.hasToken(0)) {
ArrayToken arrayOfControl = ((ArrayToken) controlInput.get(0));
ArrayToken uArray = (ArrayToken) arrayOfControl.getElement(0);
_uValue = new double[arrayOfControl.length()]
[uArray.length()]; for (int i = 0; i < _uValue.length; i++) {
for (int it_u = 0; it_u < _uValue[0].length; it_u++) {
uArray = (ArrayToken) arrayOfControl.getElement(i);
_uValue[i][it_u] = ((DoubleToken) uArray.getElement(it_u))
.doubleValue();
}
}
}

if (currentState.hasToken(0)) {
_currentState = new double[_labels.length];
RecordToken incoming = (RecordToken)
currentState.get(0); for (int it = 0; it < _labels.length; it++) {
_currentState[it] = ((DoubleToken) incoming.get(_labels[it]))
.doubleValue();
}
}

calcPredict();
predictedStates.send(0, new
ArrayToken(_predictedStates)); DoubleMatrixToken[]
jacobianResult = new
DoubleMatrixToken[_jacobianOfStates.length];
for (int i = 0; i < jacobianResult.length; i++)
{
jacobianResult[i] = new DoubleMatrixToken(_jacobianOfStates[i]);
}
jacobianOfStates.send(0, new ArrayToken(jacobianResult));
}

@Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == timeHorizon) {
_timeHorizon = ((IntToken) timeHorizon.getToken()).intValue();
}
}

private int
_timeHorizon; private
String[] _labels; private
Type[] _types;
private double[]
_currentState; private
double[][] _uValue;
private RecordToken[]
_predictedStates; private double[][][]
_jacobianOfStates;

private void calcPredict() throws IllegalActionException {


_predictedStates = new RecordToken[_timeHorizon];

_jacobianOfStates = new double[_timeHorizon][2][_uValue.length


*
_uValue[0].length]; int
predict_step = 0;
DoubleToken[] result_values = new DoubleToken[_labels.length];
result_values[0] = new DoubleToken(_currentState[0] + _uValue[0]
[0]); result_values[1] = new DoubleToken(_currentState[1] +
_uValue[0][1]); for (int it_val = 2; it_val < result_values.length; it_val+
+) {
result_values[it_val] = new DoubleToken(_currentState[it_val]);
}
_predictedStates[predict_step] = new
RecordToken(_labels, result_values);
for (int row = 0; row < _jacobianOfStates[0].length; row++) {
for (int col = 0; col < _jacobianOfStates[0][0].length; col++)
{
_jacobianOfStates[predict_step][row][col] = 0;
}
_jacobianOfStates[predict_step][row][row] = 1;
}
for (predict_step = 1; predict_step < _timeHorizon; predict_step++)
{ int control_step = Math.min(_uValue.length - 1, predict_step);
result_values[0] = new DoubleToken(
result_values[0].doubleValue() + _uValue[control_step]
[0]); result_values[1] = new DoubleToken(
result_values[1].doubleValue() + _uValue[control_step]
[1]); for (int it_val = 2; it_val < result_values.length; it_val++) {
result_values[it_val] = new
DoubleToken( result_values[it_val].
doubleValue());
}
_predictedStates[predict_step] = new
RecordToken(_labels, result_values);
double[][] dUm_dU = new double[2][_uValue.length
* _uValue[0].length];
for (int row = 0; row < dUm_dU.length; row++) {
for (int col = 0; col < dUm_dU[0].length; col++)
{
dUm_dU[row][col] = 0;
}
dUm_dU[row][control_step * 2 + row] = 1;
}
double[][] dXn_dXn_1 = DoubleMatrixMath.identityMatrixDouble(2);
double[][] dXn_dUm = DoubleMatrixMath.identityMatrixDouble(2); double[]
[] dXn_dU_via_Xn_1 = DoubleMatrixMath.multiply(dXn_dXn_1,
_jacobianOfStates[predict_step - 1]);
double[][] dXn_dU_via_Um =
DoubleMatrixMath.multiply(dXn_dUm, dUm_dU);
for (int row = 0; row < _jacobianOfStates[0].length; row++) {
for (int col = 0; col < _jacobianOfStates[0][0].length; col++)
{
_jacobianOfStates[predict_step][row][col] = dXn_dU_via_Xn_1[row][col]
+ dXn_dU_via_Um[row][col];
}
}
}
}
}
package ptolemy.actor.lib.gui;

import ptolemy.data.IntToken;
import
ptolemy.data.expr.Parameter;
import ptolemy.data.type.BaseType;
import
ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.plot.Plot;
public class XYScope extends XYPlotter {
public XYScope(CompositeEntity container, String name)
throws IllegalActionException, NameDuplicationException
{ super(container, name);
persistence = new Parameter(this, "persistence", new
IntToken(100)); persistence.setTypeEquals(BaseType.INT);
}
public Parameter
persistence; @Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == persistence && plot != null) {
int persValue = ((IntToken)
persistence.getToken()).intValue(); ((Plot)
plot).setPointsPersistence(persValue);
} else {
super.attributeChanged(attribute);
}
}
@Override
public void initialize() throws IllegalActionException
{ super.initialize();

int persValue = ((IntToken)


persistence.getToken()).intValue(); ((Plot)
plot).setPointsPersistence(persValue);
plot.repaint();
if (((Plot) plot).getMarksStyle().equals("none"))
{ ((Plot) plot).setMarksStyle("pixels");
}
}
@Override
public boolean postfire() throws IllegalActionException
{ boolean result = super.postfire();
plot.repaint();
Thread.yield()
; return result;
}
}
package ptolemy.actor.lib;

import ptolemy.actor.Director;
import
ptolemy.actor.SuperdenseTimeDirector;
import ptolemy.data.Token;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Workspace;

public class MicrostepDelay extends Transformer {

public MicrostepDelay(CompositeEntity container, String name)


throws NameDuplicationException, IllegalActionException
{
super(container, name);

output.setTypeSameAs(input);
}

@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ MicrostepDelay newObject = (MicrostepDelay) super.clone(workspace);
newObject.output.setTypeSameAs(newObject.input);
return newObject;
}

@Override
public void declareDelayDependency() throws IllegalActionException {
_declareDelayDependency(input, output, 0.0);
}

@Override
public void fire() throws IllegalActionException
{ super.fire();
if (_pendingOutput != null) {
output.send(0,
_pendingOutput); if
(_debugging) {
_debug("Sending output. Value = " + _pendingOutput);
}
} else {
output.send(0,
null); if
(_debugging) {
_debug("Nothing to send. Asserting absent output at time "
+ getDirector().getModelTime());
}
}
}

@Override
public void initialize() throws IllegalActionException
{ super.initialize();
_pendingOutput = null;
if (!(getDirector() instanceof SuperdenseTimeDirector))
{ throw new IllegalActionException(this,
"MicrostepDelay can only be used with a director that implements "
+ "SuperdenseTimeDirector, such as ContinuousDirector or
DEDirector.");
}
}

@Override
public boolean isStrict()
{ return false;
}

@Override
public boolean postfire() throws IllegalActionException
{ Director director = getDirector();
if (input.hasToken(0)) {
_pendingOutput = input.get(0);
director.fireAt(this,
director.getModelTime()); if (_debugging) {
_debug("Read input with value = " + _pendingOutput);
}
} else {
_pendingOutput = null;
}
return super.postfire();
}

protected Token _pendingOutput;


}

RESULT:

The results of Robot Model Predictive Control (MPC) within the Ptolemy software
demonstrate a significant improvement in the robotic system's ability to navigate
complex environments safely. By implementing the MPC algorithm, the robots exhibit
increased adaptability and responsiveness to unexpected obstacles, effectively
avoiding collisions and maintaining smooth trajectories. This integration of MPC in
Ptolemy showcases a promising approach for enhancing the autonomy and efficiency
of robotic systems in various applications, such as manufacturing, logistics, and
exploration.
CLIP PLAYER - CAPECODE SYSTEM

AIM:

To analyze and evaluate the impact of Clip Player - CapeCode System by


modifying system parameters on time-plots within the Ptolemy software
environment. This involves systematically observing and documenting the changes
in the time-plots' characteristics as a result of editing various parameters. The goal
is to gain insights into the system's behavior under different configurations, which
can be useful for optimizing performance and enhancing overall understanding of
the software's functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The Clip Player - CapeCode system to be analyzed along with its
associated time-plots should be identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:

OUTPUT SCREENSHOT:
SOURCE CODE:
"use strict";

var cameras =
require("@accessors-modules/cameras"); var camera;
var handle = null;

exports.setup = function () {
this.input('trigger');
this.output('image');
this.parameter('triggered', {
'type':
'boolean',
'value': false
});
this.parameter('maxFrameRate',
{ 'type': 'number',
'value': 25
});
this.parameter('camera',
{ 'type': 'string',
'value': 'default camera'
});
this.parameter('viewSize',
{ 'type': 'JSON'
});
try {
this.parameter('camera', {
'options':
cameras.cameras()
});
camera = new
cameras.Camera(this.getParameter('camera'));
this.parameter('viewSize', {
'value':
camera.getViewSize(),
'options': camera.viewSizes()
});
} catch (err)
{ error(err)
;
}
};

exports.initialize = function () {
camera.setViewSize(this.getParameter('viewSize'));
camera.open();
var self = this;
if (this.getParameter('triggered')) {
camera.on('snapshot', function (image)
{ self.send('image', image);
});

handle = this.addInputHandler('trigger', function ()


{ camera.snapshot();
});
} else {
var maxFrameRate =
self.getParameter('maxFrameRate'); var frameInterval =
1000.0/maxFrameRate; // In ms.
var lastFrameTime = 0;
camera.on('image', function (image) {
var currentTime = Date.now();
if (currentTime - lastFrameTime >= frameInterval)
{ self.send('image', image);
lastFrameTime = currentTime;
}
});
}
};
exports.wrapup = function () {
camera.removeAllListeners('image')
; if (handle !== null) {
this.removeInputHandler(handle);
}
camera.close();
};

"use strict";

var aprilTags =

require('aprilTags'); exports.setup

= function () {
this.input('input');
this.output('output');
this.output('tags');
this.input('options', {
'type': 'JSON',
'value': ''
});
};

var handle;
exports.initialize = function ()
{ var self = this;
handle = this.addInputHandler('input', function ()
{ var options = self.get('options');
var image = self.get('input');
var result = aprilTags.filter(image,
options); self.send('output', result);
var tags =
aprilTags.tags(); if (tags) {
self.send('tags', tags);
}
});
};

exports.wrapup = function ()
{ if (handle) {
this.removeInputHandler(handle);
}
};
exports.setup = function()
{ this.input('tags');
this.input('frames');
this.output('newTag');
}
exports.initialize = function() {
var self = this; // For use inside handler
functions. var tagsSeen = [];
this.addInputHandler('frames', function() {
// Although this is triggered by frames, we are interested in
tags. var tags = this.get('tags');
if (!tags || tags.length === 0)
{ tagsSeen = [];
return;
}
var currentTags = [];
for (var i = 0; i < tags.length; i++) {
currentTags[tags[i].id] =
true; if (!tagsSeen[tags[i].id])
{
// Have not seen this tag
before. self.send('newTag',
tags[i].id);
}
}
tagsSeen = currentTags;
});
}

var aprilTags = require('aprilTags');


exports.setup = function ()
{ this.input('input');
this.output('output');
this.output('tags');
this.input('options', {
'type': 'JSON',
'value': ''
});
};

var handle;
exports.initialize = function ()
{ var self = this;
handle = self.addInputHandler('input', function ()
{ var options = self.get('options');
var image = self.get('input');
var result = aprilTags.filter(image,
options); self.send('output', result);
var tags =
aprilTags.tags(); if (tags) {
self.send('tags', tags);
}
});
};

exports.wrapup = function ()
{ if (handle) {
this.removeInputHandler(handle);
}
};

exports.initialize = function () {
camera.setViewSize(this.getParameter('viewSize'));
camera.open();
var self = this;
if (this.getParameter('triggered')) {
// Request a snapshot. Note the video stream might not be playing.
// An event will be generated when a snapshot is
available. camera.on('snapshot', function (image) {
self.send('image', image);
});

handle = this.addInputHandler('trigger', function ()


{ camera.snapshot();
});
} else {
var maxFrameRate =
self.getParameter('maxFrameRate'); var frameInterval =
1000.0/maxFrameRate; // In ms.
var lastFrameTime = 0;
camera.on('image', function (image) {
var currentTime = Date.now();
if (currentTime - lastFrameTime >= frameInterval)
{ self.send('image', image);
lastFrameTime = currentTime;
}
});
}
};

/** Remove handlers and close the camera.


*/ exports.wrapup = function () {
camera.removeAllListeners('image')
; if (handle !== null) {
this.removeInputHandler(handle);
}
camera.close();
};

RESULT:

The integration of a CliP Player - CapeCode in Ptolemy software has yielded


several notable results. These include enhanced visualization capabilities, improved
data processing efficiency, and the ability to incorporate advanced image analysis
algorithms. This integration allows users to seamlessly integrate camera data into
Ptolemy models, enabling real-time monitoring and analysis of complex systems.
Additionally, the use of JavaScript offers a user-friendly programming interface,
making it easier for developers to create customized image processing pipelines
and extend the software's functionality. Overall, this integration has expanded the
applicability of Ptolemy in various domains, particularly those involving image
processing and real-time data acquisition.
FUEL TANK SYSTEM

AIM:

To analyze and evaluate the impact of Fuel Tank System by modifying system
parameters on time-plots within the Ptolemy software environment. This involves
systematically observing and documenting the changes in the time-plots'
characteristics as a result of editing various parameters. The goal is to gain
insights into the system's behavior under different configurations, which can be
useful for optimizing performance and enhancing overall understanding of the
software's functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The Fuel Tank system to be analyzed along with its associated time-plots should
be identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:

STRUCTURE OF ACTORS USED:


OUTPUT SCREENSHOTS:
SOURCE CODE:
import ptolemy.data.DoubleToken;
import ptolemy.data.expr.Parameter;
import
ptolemy.data.expr.StringParameter;
import ptolemy.data.type.BaseType;
import ptolemy.domains.continuous.kernel.ContinuousDirector;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Workspace;
public class LevelCrossingDetector extends TypedAtomicActor

public LevelCrossingDetector(CompositeEntity container, String


name) throws IllegalActionException, NameDuplicationException
{
super(container, name);

output = new TypedIOPort(this, "output", false, true);

trigger = new TypedIOPort(this, "trigger", true,


false); trigger.setMultiport(false);
trigger.setTypeEquals(BaseType.DOUBLE);
level = new Parameter(this, "level", new
DoubleToken(0.0));
level.setTypeEquals(BaseType.DOUBLE);

value = new Parameter(this,


"value");
value.setExpression("level");
direction = new StringParameter(this,
"direction"); direction.setExpression("both");
_detectRisingCrossing = true;
_detectFallingCrossing = true;

direction.addChoice("both");
direction.addChoice("falling")
;
direction.addChoice("rising");

output.setTypeAtLeast(value);

_errorTolerance = 1e-4;
errorTolerance = new Parameter(this,
"errorTolerance", new
DoubleToken(_errorTolerance));
errorTolerance.setTypeEquals(BaseType.DOUBLE);
}
public StringParameter
direction; public Parameter
errorTolerance; public Parameter
level;
public Parameter value;
public TypedIOPort output;
public TypedIOPort
trigger; @Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == errorTolerance) {
double tolerance = ((DoubleToken) errorTolerance.getToken())
.doubleValue();

if (tolerance <= 0.0) {


throw new IllegalActionException(this,
"Error tolerance must be greater than 0.");
}

_errorTolerance = tolerance;
} else if (attribute == direction) {
String crossingDirections = direction.stringValue();
if (crossingDirections.equalsIgnoreCase("falling")) {
_detectFallingCrossing = true;
_detectRisingCrossing = false;
} else if (crossingDirections.equalsIgnoreCase("rising")) {
_detectFallingCrossing = false;
_detectRisingCrossing = true;
} else if (crossingDirections.equalsIgnoreCase("both")) {
_detectFallingCrossing = true;
_detectRisingCrossing = true;
} else {
throw new IllegalActionException(
"Unknown direction: " + crossingDirections);
}
} else if (attribute == level) {
_level = ((DoubleToken) level.getToken()).doubleValue();
} else {

super.attributeChanged(attribute);
}
}
@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ LevelCrossingDetector newObject = (LevelCrossingDetector) super.clone(
workspace);
newObject.output.setTypeAtLeast(newObject.value);
return newObject;
}
@Override
public void declareDelayDependency() throws IllegalActionException {
_declareDelayDependency(trigger, output, 0.0);
}

@Override
public void fire() throws IllegalActionException {
ContinuousDirector dir = (ContinuousDirector)
getDirector(); double currentStepSize =
dir.getCurrentStepSize();
int microstep = dir.getIndex();
_postponedOutputProduced = false;

if (_debugging) {
_debug("Called fire() at time " + dir.getModelTime()
+ " with microstep " + microstep + " and step size "
+ currentStepSize);
}

if (_postponed > 0 && _postponed <= microstep) {


if (_debugging) {
_debug("-- Produce postponed output.");
}
output.send(0, value.getToken());
_postponedOutputProduced = true;
} else {
if (_debugging) {
_debug("-- Output is absent.");
}
output.sendClear(0);
}
if (trigger.getWidth() > 0 &&
trigger.isKnown(0) &&
trigger.hasToken(0)) {
_thisTrigger = ((DoubleToken)
trigger.get(0)).doubleValue(); if (_debugging) {
_debug("-- Consumed a trigger input: " + _thisTrigger);
_debug("-- Last trigger is: " + _lastTrigger);
}

if (_lastTrigger == Double.NEGATIVE_INFINITY)
{ return;
}

boolean inputIsIncreasing = _thisTrigger > _lastTrigger;


boolean inputIsDecreasing = _thisTrigger < _lastTrigger;

if ((_lastTrigger - _level) * (_thisTrigger - _level) < 0.0


|| _thisTrigger == _level) {
if (_detectFallingCrossing && inputIsDecreasing
|| _detectRisingCrossing && inputIsIncreasing)
{ if (currentStepSize != 0.0 && Math
.abs(_thisTrigger - _level) >= _errorTolerance)
{ if (_debugging) {
_debug("-- Missed an event. Step size will be adjusted.");
}
_eventMissed = true;
} else {
_postponed = microstep + 1;
}
}
}
}
}
@Override
public void initialize() throws IllegalActionException
{ super.initialize();
_eventMissed = false;
_level = ((DoubleToken) level.getToken()).doubleValue();
_lastTrigger = Double.NEGATIVE_INFINITY;
_thisTrigger = _lastTrigger;
_postponed = 0;
_postponedOutputProduced = false;
}
@Override
public boolean isStepSizeAccurate()
{ if (_debugging) {
_debug("Step size is accurate: " + !_eventMissed);
}
return !_eventMissed;
}
@Override
public boolean isStrict()
{ return false;
}
@Override
public boolean postfire() throws IllegalActionException
{ if (_debugging) {
_debug("Called postfire().");
}

_lastTrigger = _thisTrigger;
_eventMissed =
false; if (_postponed
> 0) { if
(_debugging) {
_debug("Requesting refiring at the current time.");
}
getDirector().fireAtCurrentTime(this);
}
if (_postponedOutputProduced) {
_postponedOutputProduced = false;
ContinuousDirector dir = (ContinuousDirector)
getDirector(); int microstep = dir.getIndex();
if (microstep >= _postponed) {
_postponed = 0;
}
}
return super.postfire();
}
@Override
public void preinitialize() throws IllegalActionException
{ if (!(getDirector() instanceof ContinuousDirector)) {
throw new IllegalActionException("LevelCrossingDetector can only"
+ " be used inside Continuous domain.");
}
super.preinitialize();
}

@Override
public double refinedStepSize() {
ContinuousDirector dir = (ContinuousDirector)
getDirector(); double refinedStep = dir.getCurrentStepSize();

if (_eventMissed) {
refinedStep = (Math.abs(_lastTrigger - _level)
+ _errorTolerance / 2) * dir.getCurrentStepSize()
/ Math.abs(_thisTrigger - _lastTrigger);

if (_debugging) {
_debug(getFullName() + "-- Event Missed: refine step to "
+ refinedStep);
}
_eventMissed = false;
}
return refinedStep;
}

/** Return the maximum Double value. This actor does not suggest
* or constrain the step size for the next iteration.
* @return java.Double.MAX_VALUE.
*/
@Overrid
e
public double suggestedStepSize() {
return java.lang.Double.MAX_VALUE;
}
protected double _level;
private boolean _detectRisingCrossing;
private boolean
_detectFallingCrossing; private double
_errorTolerance;
private boolean _eventMissed =
false; private double _lastTrigger;
private int _postponed;
private boolean
_postponedOutputProduced; private double
_thisTrigger;
}

public class TimedPlotter extends Plotter implements TimedActor


{ public TimedPlotter(CompositeEntity container, String name)
throws IllegalActionException, NameDuplicationException
{ super(container, name);
disconnectGraphOnAbsentValue = new Parameter(this,
"disconnectGraphOnAbsentValue", new BooleanToken(false));
disconnectGraphOnAbsentValue.setTypeEquals(BaseType.BOOLEAN);
input = new TypedIOPort(this, "input", true, false);
input.setMultiport(true);
input.setTypeEquals(BaseType.DOUBLE);

useLocalTime = new Parameter(this,


"useLocalTime");
useLocalTime.setTypeEquals(BaseType.BOOLEAN);
useLocalTime.setExpression("false");
}
public Parameter

disconnectGraphOnAbsentValue; public

Parameter useLocalTime;

@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ TimedPlotter newObject = (TimedPlotter) super.clone(workspace);
newObject._connected = new ArrayList<Boolean>();
return newObject;
}

@Override
public boolean prefire() throws IllegalActionException
{ super.prefire();

int width = input.getWidth();


if (width != _connected.size()) {
_connected.clear();
for (int i = 0; i < width; i++) {
_connected.add(true);
}
}
return true;
}

@Override
public void initialize() throws IllegalActionException
{ super.initialize();
int width = input.getWidth();
_connected.clear();
for (int i = 0; i < width; i++) {
_connected.add(true);
}
((PlotInterface) plot).markDisconnections(true);
}
@Override
public boolean postfire() throws IllegalActionException
{ double currentTimeValue;
int width = input.getWidth();

boolean disconnectOnAbsent = ((BooleanToken) disconnectGraphOnAbsentValue


.getToken()).booleanValue();
int offset = ((IntToken)
startingDataset.getToken()).intValue(); PlotInterface plot =
(PlotInterface) this.plot;
for (int i = width - 1; i >= 0; i--)
{ if (input.hasToken(i)) {
boolean localTime = ((BooleanToken) useLocalTime.getToken())
.booleanValue()
; if (localTime) {
currentTimeValue = input.getModelTime(i).getDoubleValue();
} else {
currentTimeValue = getDirector().getGlobalTime()
.getDoubleValue();
}

DoubleToken currentToken = (DoubleToken) input.get(i);


SmoothToken smoothToken = currentToken instanceof SmoothToken
? (SmoothToken) currentToken
: null;
double[] derivatives;
if (smoothToken != null) {
derivatives =
smoothToken.derivativeValues(); if
(derivatives == null) {
derivatives = new double[0];
}
} else {
derivatives = null;
}
plot.addPoint(i + offset, currentTimeValue,
currentToken.doubleValue(), derivatives,
_connected.get(i));
if (disconnectOnAbsent) {
_connected.set(i, true);
}
} else if (disconnectOnAbsent) {
_connected.set(i, false);
}
}

return super.postfire();
}

private ArrayList<Boolean> _connected = new ArrayList<Boolean>();


}

RESULT:

In Ptolemy, when analyzing the results of a fuel system model, the parameters can be
edited to observe their effects on the time-plots. By modifying factors such as fuel
pressure, flow rate, or temperature, one can visualize how these changes influence
the system's behavior over time. The purpose of this analysis is to identify optimal
configurations for efficient fuel management, ensuring smooth performance and
minimizing potential issues.
AIR MANAGEMENT SYSTEM

AIM:

To analyze and evaluate the impact of Air Management System by modifying


system parameters on time-plots within the Ptolemy software environment. This
involves systematically observing and documenting the changes in the time-plots'
characteristics as a result of editing various parameters. The goal is to gain insights
into the system's behavior under different configurations, which can be useful for
optimizing performance and enhancing overall understanding of the software's
functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The system to be analyzed along with its associated time-plots should
be identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:
STRUCTURE OF ACTORS USED:

OUTPUT SCREENSHOT:
SOURCE CODE:
package ptolemy.actor.lib;
import java.util.HashMap;
import java.util.Iterator;
import
java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ptolemy.actor.IOPort; import
ptolemy.actor.TypedAtomicActor; import ptolemy.actor.TypedIOPort;
import ptolemy.data.DoubleToken; import ptolemy.data.IntToken;
import ptolemy.data.Token;
import ptolemy.data.expr.ASTPtRootNode; import
ptolemy.data.expr.ModelScope; import ptolemy.data.expr.ParseTreeEvaluator;
import ptolemy.data.expr.ParseTreeFreeVariableCollector;
import ptolemy.data.expr.ParseTreeTypeInference; import
ptolemy.data.expr. PtParser;
import ptolemy.data.expr.Variable; import ptolemy.data.type.BaseType;
import ptolemy.data.type.MonotonicFunction; import ptolemy.data.type.Type;
import ptolemy.data.type.TypeConstant; import
ptolemy.graph.InequalityTerm; import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute; import
ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Settable;
import
ptolemy.kernel.util.StringAttribute;
import ptolemy.kernel.util.Workspace;
public class Expression extends TypedAtomicActor {
public Expression(CompositeEntity container, String
name)
throws NameDuplicationException, IllegalActionException
{ super(container, name);

output = new TypedIOPort(this, "output", false,


true); expression = new StringAttribute(this,
"expression"); expression.setExpression("");
Parameter hide = new Parameter(expression,
"_hide"); hide.setExpression("true");
hide.setVisibility(Settable.NONE);

_setOutputTypeConstraint();
}

public TypedIOPort output;


public StringAttribute
expression;
@Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == expression) {
_parseTree = null;
}
}

@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ Expression newObject = (Expression) super.clone(workspace );
newObject.expression.copy(this.expression);
return newObject;
}

private void _setOutputTypeConstraint()


{ Type outputType = Type.DOUBLE;
if (expression.stringValue().contains("rand("))
{ outputType = Type.DOUBLE;
} else if (expression.stringValue().contains("range("))
{ outputType = Type.INT;
}

output.setTypeEquals(outputType);
}

private Type _inferType(String expressionString) {


ParseTreeTypeInference inference = new
ParseTreeTypeInference();
inference.setExpression(expressionString);
return inference.getType();
}

private void _collectFreeVariables(List<Variable>


variables, String expressionString) {
ParseTreeEvaluator evaluator = new
ParseTreeEvaluator();
evaluator.setExpression(expressionString);
evaluator.collectFreeVariables(variables);
}

private void _parseExpression() {


String expressionString = expression.stringValue();

if (expressionString.startsWith("_hide") || expressionString.isEmpty()) {
_parseTree =
null; return;
}

_collectFreeVariables(_freeVariables, expressionString);
Type inferredType = _inferType(expressionString);
if (inferredType instanceof TypeConstant) {
_parseTree = new ASTPtRootNode(expressionString);
_parseTree.setType(_getConstantType(inferredType));
} else {
PtParser parser = new
PtParser(expressionString);
parser.setTypeInference(inferredType);
_parseTree = parser.parse();
}
}

private Type _getConstantType(TypeConstant typeConstant)


{ if (typeConstant instanceof MonotonicFunction) {
return ((MonotonicFunction) typeConstant).getDomain().getRange().get(0);
}
return typeConstant;
}

private ASTPtRootNode _parseTree;


private List<Variable> _freeVariables = new LinkedList<>();

@Override
public void init() throws Exception
{ super.init();
_parseExpression();
}

@Override
public synchronized void fire() throws RuntimeException
{ if (_parseTree == null) {
output.send(0, new
DoubleToken(0)); return;
}

Map<Variable, Object> bindings = new


HashMap<>(); Set<Variable> variables =
_freeVariables.keySet();
for (Variable variable : variables) {
Object value =
getPortToken(variable); if (value !=
null) {
bindings.put(variable, value);
}
}
Token result = _parseTree.evaluate(bindings, new
ModelScope(this)); if (result instanceof DoubleToken) {
output.send(0, result);
} else {
throw new RuntimeException("Invalid result type: " +
result.getClass(). getName()); } }
private Object getPortToken(Variable variable)
{ for (IOPort port : getPorts()) {
if (port instanceof Settable) {
Token token = ((Settable) port).getAndReset();
if (token != null && variable.matches(token)) {
return token.toJava();
}
}
}
return null;
}

RESULT:

In Ptolemy, the results of the Air Management System can be observed by analyzing
the time-plots after editing specific parameters. By modifying these parameters, the
system's performance, efficiency, and responsiveness may change. Key observations
to note include variations in response time, resource allocation, and overall system
stability. The results can provide valuable insights for fine-tuning the Air Management
System, ultimately leading to improved performance and better management of
resources within the software.
COLLISION AVOIDANCE SYSTEM

AIM:

To analyze and evaluate the impact of Collision Avoidance System by modifying


system parameters on time-plots within the Ptolemy software environment. This
involves systematically observing and documenting the changes in the time-plots'
characteristics as a result of editing various parameters. The goal is to gain
insights into the system's behavior under different configurations, which can be
useful for optimizing performance and enhancing overall understanding of the
software's functionality.

SOFTWARE REQUIRED:
 Ptolemy II (supports various domain-specific languages and provides a user-
friendly environment for editing system parameters and observing their
effects on time-plots.)

PROCEDURE:

1. The Ptolemy software interface and its components should be familiarized with.
2. The Collision Avoidance system to be analyzed along with its associated time-
plots should be
identified.
3. A parameter within the system for modification should be selected.
4. The chosen parameter's value or configuration should be edited,
ensuring documentation of the original and altered settings.
5. The simulation or analysis should be run with the modified parameter.
6. The resulting time-plot should be observed and compared with the original
one, noting any significant changes in characteristics such as amplitude,
frequency,
or shape.
7. Steps 3-6 should be repeated for other parameters within the system to
understand their individual effects on the time-plots.
8. The observed changes should be analyzed to draw conclusions about the
system's behavior under different parameter configurations.
9. Documentation should include the original and modified parameter values, the
observed time-plot changes, and any insights gained about the system's
performance.
10. The results should be shared with relevant stakeholders, and the gathered
information should be used to optimize the system's performance or improve
the Ptolemy software's functionality.
CIRCUIT DIAGRAM:

STRUCTURE OF ACTORS USED:


OUTPUT SCREENSHOT:
SOURCE CODE:
package ptolemy.actor.lib;

import ptolemy.actor.Director;
import
ptolemy.actor.SuperdenseTimeDirector;
import ptolemy.data.Token;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Workspace;

public class MicrostepDelay extends Transformer {


public MicrostepDelay(CompositeEntity container, String name)
throws NameDuplicationException, IllegalActionException {
super(container, name);

output.setTypeSameAs(input);
}
@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ MicrostepDelay newObject = (MicrostepDelay) super.clone(workspace);
newObject.output.setTypeSameAs(newObject.input);
return newObject;
}
@Override
public void declareDelayDependency() throws IllegalActionException {
_declareDelayDependency(input, output, 0.0);
}
@Override
public void fire() throws IllegalActionException
{ super.fire();
if (_pendingOutput != null) {
output.send(0,
_pendingOutput); if
(_debugging) {
_debug("Sending output. Value = " + _pendingOutput);
}
} else {
output.send(0,
null); if
(_debugging) {
_debug("Nothing to send. Asserting absent output at time "
+ getDirector().getModelTime());
}
}
}
@Override
public void initialize() throws IllegalActionException
{ super.initialize();
_pendingOutput = null;

if (!(getDirector() instanceof SuperdenseTimeDirector))


{ throw new IllegalActionException(this,
"MicrostepDelay can only be used with a director that implements "
+ "SuperdenseTimeDirector, such as ContinuousDirector or
DEDirector.");
}
}
@Override
public boolean isStrict()
{ return false;
}
@Override
public boolean postfire() throws IllegalActionException
{ Director director = getDirector();
if (input.hasToken(0)) {
_pendingOutput = input.get(0);
director.fireAt(this,
director.getModelTime()); if (_debugging) {
_debug("Read input with value = " + _pendingOutput);
}
} else {
_pendingOutput = null;
}
return super.postfire();
}
protected Token _pendingOutput;
}
package org.ptolemy.ssm;

import
ptolemy.actor.TypedAtomicActor;
import ptolemy.actor.TypedIOPort;
import ptolemy.data.ArrayToken;
import
ptolemy.data.DoubleMatrixToken;
import ptolemy.data.DoubleToken;
import ptolemy.data.IntToken;
import ptolemy.data.RecordToken;
import ptolemy.data.StringToken;
import ptolemy.data.expr.Parameter;
import
ptolemy.data.type.ArrayType;
import ptolemy.data.type.BaseType;
import
ptolemy.data.type.RecordType;
import ptolemy.data.type.Type;
import
ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.math.DoubleMatrixMath;

public class StatePredictorWithControl extends TypedAtomicActor {


public StatePredictorWithControl(CompositeEntity container, String
name) throws NameDuplicationException, IllegalActionException {
super(container, name);
controlInput = new TypedIOPort(this, "control_input", true,
false); controlInput
.setTypeEquals(new ArrayType(new ArrayType(BaseType.DOUBLE)));

currentState = new TypedIOPort(this, "current_state", true,


false); ArrayToken names = new ArrayToken("{\"x\",\"y\"}");
String stateName;
_labels = new String[names.length()];
_types = new Type[names.length()];
for (int i = 0; i < names.length(); i++)
{
stateName = ((StringToken) names.getElement(i)).stringValue();
_labels[i] = stateName;
_types[i] = BaseType.DOUBLE;
}
currentState.setTypeEquals(new RecordType(_labels, _types));
predictedStates = new TypedIOPort(this, "predicted_states", false,
true);
predictedState
s
.setTypeEquals(new ArrayType(new RecordType(_labels, _types)));

jacobianOfStates = new TypedIOPort(this, "jacobianOfStates",


false, true);
jacobianOfStates.setTypeEquals(new ArrayType(BaseType.DOUBLE_MATRIX));

_timeHorizon = 1;
timeHorizon = new Parameter(this, "prediction
horizon"); timeHorizon.setExpression("1");
timeHorizon.setTypeEquals(BaseType.INT);
}
public Parameter timeHorizon;
public TypedIOPort controlInput;
public TypedIOPort currentState;
public TypedIOPort predictedStates;
public TypedIOPort
jacobianOfStates; @Override
public void fire() throws IllegalActionException {

super.fire();
if (controlInput.hasToken(0)) {
ArrayToken arrayOfControl = ((ArrayToken) controlInput.get(0));
ArrayToken uArray = (ArrayToken) arrayOfControl.getElement(0);
_uValue = new double[arrayOfControl.length()]
[uArray.length()]; for (int i = 0; i < _uValue.length; i++) {
for (int it_u = 0; it_u < _uValue[0].length; it_u++) {
uArray = (ArrayToken) arrayOfControl.getElement(i);
_uValue[i][it_u] = ((DoubleToken) uArray.getElement(it_u))
.doubleValue();
}
}
}

if (currentState.hasToken(0)) {
_currentState = new double[_labels.length];
RecordToken incoming = (RecordToken)
currentState.get(0); for (int it = 0; it < _labels.length; it++) {
_currentState[it] = ((DoubleToken) incoming.get(_labels[it]))
.doubleValue();
}
}

calcPredict();
predictedStates.send(0, new
ArrayToken(_predictedStates)); DoubleMatrixToken[]
jacobianResult = new
DoubleMatrixToken[_jacobianOfStates.length];
for (int i = 0; i < jacobianResult.length; i++)
{
jacobianResult[i] = new DoubleMatrixToken(_jacobianOfStates[i]);
}
jacobianOfStates.send(0, new ArrayToken(jacobianResult));
}

@Override
public void attributeChanged(Attribute
attribute) throws IllegalActionException {
if (attribute == timeHorizon) {
_timeHorizon = ((IntToken) timeHorizon.getToken()).intValue();
}
}
private int
_timeHorizon; private
String[] _labels; private
Type[] _types;
private double[]
_currentState; private
double[][] _uValue;
private RecordToken[]
_predictedStates; private double[][][]
_jacobianOfStates;

private void calcPredict() throws IllegalActionException {


_predictedStates = new RecordToken[_timeHorizon];

_jacobianOfStates = new double[_timeHorizon][2][_uValue.length


*
_uValue[0].length]; int
predict_step = 0;
DoubleToken[] result_values = new DoubleToken[_labels.length];
result_values[0] = new DoubleToken(_currentState[0] + _uValue[0]
[0]); result_values[1] = new DoubleToken(_currentState[1] +
_uValue[0][1]); for (int it_val = 2; it_val < result_values.length; it_val+
+) {
result_values[it_val] = new DoubleToken(_currentState[it_val]);
}
_predictedStates[predict_step] = new
RecordToken(_labels, result_values);
for (int row = 0; row < _jacobianOfStates[0].length; row++) {
for (int col = 0; col < _jacobianOfStates[0][0].length; col++)
{
_jacobianOfStates[predict_step][row][col] = 0;
}
_jacobianOfStates[predict_step][row][row] = 1;
}

for (predict_step = 1; predict_step < _timeHorizon; predict_step++)


{ int control_step = Math.min(_uValue.length - 1, predict_step);
result_values[0] = new DoubleToken(
result_values[0].doubleValue() + _uValue[control_step]
[0]); result_values[1] = new DoubleToken(
result_values[1].doubleValue() + _uValue[control_step]
[1]); for (int it_val = 2; it_val < result_values.length; it_val++) {
result_values[it_val] = new
DoubleToken( result_values[it_val].
doubleValue());
}
_predictedStates[predict_step] = new
RecordToken(_labels, result_values);
double[][] dUm_dU = new double[2][_uValue.length
* _uValue[0].length];
for (int row = 0; row < dUm_dU.length; row++) {
for (int col = 0; col < dUm_dU[0].length; col++)
{
dUm_dU[row][col] = 0;
}
dUm_dU[row][control_step * 2 + row] = 1;
}
double[][] dXn_dXn_1 = DoubleMatrixMath.identityMatrixDouble(2);
double[][] dXn_dUm = DoubleMatrixMath.identityMatrixDouble(2); double[]
[] dXn_dU_via_Xn_1 = DoubleMatrixMath.multiply(dXn_dXn_1,
_jacobianOfStates[predict_step - 1]);
double[][] dXn_dU_via_Um =
DoubleMatrixMath.multiply(dXn_dUm, dUm_dU);
for (int row = 0; row < _jacobianOfStates[0].length; row++) {
for (int col = 0; col < _jacobianOfStates[0][0].length; col++)
{
_jacobianOfStates[predict_step][row][col] = dXn_dU_via_Xn_1[row][col]
+ dXn_dU_via_Um[row][col];
}
}
}
}
}

package ptolemy.actor.lib;

import ptolemy.actor.Director;
import
ptolemy.actor.SuperdenseTimeDirector;
import ptolemy.data.Token;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.Workspace;

public class MicrostepDelay extends Transformer {

public MicrostepDelay(CompositeEntity container, String name)


throws NameDuplicationException, IllegalActionException
{
super(container, name);

output.setTypeSameAs(input);
}

@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException
{ MicrostepDelay newObject = (MicrostepDelay) super.clone(workspace);
newObject.output.setTypeSameAs(newObject.input);
return newObject;
}
@Override
public void declareDelayDependency() throws IllegalActionException {
_declareDelayDependency(input, output, 0.0);
}

@Override
public void fire() throws IllegalActionException
{ super.fire();
if (_pendingOutput != null) {
output.send(0,
_pendingOutput); if
(_debugging) {
_debug("Sending output. Value = " + _pendingOutput);
}
} else {
output.send(0,
null); if
(_debugging) {
_debug("Nothing to send. Asserting absent output at time "
+ getDirector().getModelTime());
}
}
}

@Override
public void initialize() throws IllegalActionException
{ super.initialize();
_pendingOutput = null;

if (!(getDirector() instanceof SuperdenseTimeDirector))


{ throw new IllegalActionException(this,
"MicrostepDelay can only be used with a director that implements "
+ "SuperdenseTimeDirector, such as ContinuousDirector or
DEDirector.");
}
}

@Override
public boolean isStrict()
{ return false;
}

@Override
public boolean postfire() throws IllegalActionException
{ Director director = getDirector();
if (input.hasToken(0)) {
_pendingOutput = input.get(0);
director.fireAt(this,
director.getModelTime()); if (_debugging) {
_debug("Read input with value = " + _pendingOutput);
}
} else {
_pendingOutput = null;
}
return super.postfire();
}

protected Token _pendingOutput;


}

RESULT:

The results of collision avoidance in Ptolemy software demonstrate the effectiveness


of the implemented algorithms in maintaining safe and efficient system operations.
By observing time-plots and analyzing the changes in system parameters, it becomes
evident that the software successfully prevents collisions among the interacting
components. This is achieved through the coordination of various elements, including
communication, decision-making, and control mechanisms. As a result, the overall
performance and reliability of the system are significantly improved, ensuring a safer
and more efficient environment for the involved components.

You might also like