Skip to content

Commit 2701e68

Browse files
committed
now all parts get voltages and currents depending on simulation time
1 parent cccd30e commit 2701e68

File tree

2 files changed

+68
-66
lines changed

2 files changed

+68
-66
lines changed

src/simulation/simulator.cpp

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -390,43 +390,43 @@ void Simulator::updateParts(QSet<ItemBase *> itemBases, int timeStep) {
390390
QString family = part->family().toLower();
391391

392392
if (family.contains("capacitor")) {
393-
updateCapacitor(part);
393+
updateCapacitor(timeStep, part);
394394
continue;
395395
}
396396
if (family.contains("diode")) {
397-
updateDiode(part);
397+
updateDiode(timeStep, part);
398398
continue;
399399
}
400400
if (family.contains("led")) {
401-
updateLED(part);
401+
updateLED(timeStep, part);
402402
continue;
403403
}
404404
if (family.contains("resistor")) {
405-
updateResistor(part);
405+
updateResistor(timeStep, part);
406406
continue;
407407
}
408408
if (family.contains("multimeter")) {
409-
updateMultimeter(part);
409+
updateMultimeter(timeStep, part);
410410
continue;
411411
}
412412
if (family.contains("dc motor")) {
413-
updateDcMotor(part);
413+
updateDcMotor(timeStep, part);
414414
continue;
415415
}
416416
if (family.contains("line sensor") || family.contains("distance sensor")) {
417-
updateIRSensor(part);
417+
updateIRSensor(timeStep, part);
418418
continue;
419419
}
420420
if (family.contains("battery") || family.contains("voltage source")) {
421-
updateBattery(part);
421+
updateBattery(timeStep, part);
422422
continue;
423423
}
424424
if (family.contains("potentiometer") || family.contains("sparkfun trimpot")) {
425-
updatePotentiometer(part);
425+
updatePotentiometer(timeStep, part);
426426
continue;
427427
}
428428
if (family.contains("oscilloscope")) {
429-
updateOscilloscope(part, timeStep);
429+
updateOscilloscope(timeStep, part);
430430
continue;
431431
}
432432
}
@@ -593,12 +593,14 @@ void Simulator::removeSimItems(QList<QGraphicsItem *> items) {
593593
* @param[in] defaultValue value to return on empty vector
594594
* @returns the first vector element or the given default value
595595
*/
596-
double Simulator::getVectorValueOrDefault(const std::string & vecName, double defaultValue) {
596+
double Simulator::getVectorValueOrDefault(unsigned long timeStep, const std::string & vecName, double defaultValue) {
597597
auto vecInfo = m_simulator->getVecInfo(vecName);
598-
if (vecInfo.empty()) {
598+
if (vecInfo.empty()) {
599599
return defaultValue;
600600
} else {
601-
return vecInfo[vecInfo.size()-1];
601+
if (timeStep < 0 || timeStep >= vecInfo.size())
602+
return defaultValue;
603+
return vecInfo[timeStep];
602604
}
603605
}
604606

@@ -608,7 +610,7 @@ double Simulator::getVectorValueOrDefault(const std::string & vecName, double de
608610
* @param[in] c1 the second connector
609611
* @returns the voltage between the connector c0 and c1
610612
*/
611-
double Simulator::calculateVoltage(ConnectorItem * c0, ConnectorItem * c1) {
613+
double Simulator::calculateVoltage(unsigned long timeStep, ConnectorItem * c0, ConnectorItem * c1) {
612614
int net0 = m_connector2netHash.value(c0);
613615
int net1 = m_connector2netHash.value(c1);
614616

@@ -621,12 +623,12 @@ double Simulator::calculateVoltage(ConnectorItem * c0, ConnectorItem * c1) {
621623
if (net0 != 0) {
622624
auto vecInfo = m_simulator->getVecInfo(net0str.toStdString());
623625
if (vecInfo.empty()) return 0.0;
624-
volt0 = vecInfo[0];
626+
volt0 = vecInfo[timeStep];
625627
}
626628
if (net1 != 0) {
627629
auto vecInfo = m_simulator->getVecInfo(net1str.toStdString());
628630
if (vecInfo.empty()) return 0.0;
629-
volt1 = vecInfo[0];
631+
volt1 = vecInfo[timeStep];
630632
}
631633
return volt0-volt1;
632634
}
@@ -767,13 +769,13 @@ double Simulator::getMaxPropValue(ItemBase *part, QString property) {
767769
* @param[in] subpartName The name of the subpart. Leave it empty if there is only one spice line for the device. Otherwise, give the suffix of the subpart.
768770
* @returns the power that a part is consuming/producing.
769771
*/
770-
double Simulator::getPower(ItemBase* part, QString subpartName) {
772+
double Simulator::getPower(unsigned long timeStep, ItemBase* part, QString subpartName) {
771773
//TODO: Handle devices that do not return the power
772774
QString instanceStr = part->instanceTitle().toLower();
773775
instanceStr.append(subpartName.toLower());
774776
instanceStr.prepend("@");
775777
instanceStr.append("[p]");
776-
return getVectorValueOrDefault(instanceStr.toStdString(), 0.0);
778+
return getVectorValueOrDefault(timeStep, instanceStr.toStdString(), 0.0);
777779
}
778780

779781
/**
@@ -787,7 +789,7 @@ double Simulator::getPower(ItemBase* part, QString subpartName) {
787789
* @param[in] subpartName The name of the subpart. Leave it empty if there is only one spice line for the device. Otherwise, give the suffix of the subpart.
788790
* @returns the current that a part is consuming/producing.
789791
*/
790-
double Simulator::getCurrent(ItemBase* part, QString subpartName) {
792+
double Simulator::getCurrent(unsigned long timeStep, ItemBase* part, QString subpartName) {
791793
QString instanceStr = part->instanceTitle().toLower();
792794
instanceStr.append(subpartName.toLower());
793795

@@ -820,15 +822,15 @@ double Simulator::getCurrent(ItemBase* part, QString subpartName) {
820822
break;
821823

822824
}
823-
return getVectorValueOrDefault(instanceStr.toStdString(), 0.0);
825+
return getVectorValueOrDefault(timeStep, instanceStr.toStdString(), 0.0);
824826
}
825827

826828
/**
827829
* Returns the current that flows through a transistor.
828830
* @param[in] spicePartName The name of the spice transistor.
829831
* @returns the current that the transistor is sinking/sourcing.
830832
*/
831-
double Simulator::getTransistorCurrent(QString spicePartName, TransistorLeg leg) {
833+
double Simulator::getTransistorCurrent(unsigned long timeStep, QString spicePartName, TransistorLeg leg) {
832834
if(spicePartName.at(0).toLower()!=QChar('q')) {
833835
//TODO: Add tr()
834836
throw QString("Error getting the current of a transistor. The device is not a transistor, its first letter is not a Q. Name: %1").arg(spicePartName);
@@ -848,7 +850,7 @@ double Simulator::getTransistorCurrent(QString spicePartName, TransistorLeg leg)
848850
throw QString("Error getting the current of a transistor. The transistor leg or property is not recognized. Leg: %1").arg(leg);
849851
}
850852

851-
return getVectorValueOrDefault(spicePartName.toStdString(), 0.0);
853+
return getVectorValueOrDefault(timeStep, spicePartName.toStdString(), 0.0);
852854
}
853855

854856
/**
@@ -1015,9 +1017,9 @@ void Simulator::removeItemsToBeSimulated(QList<QGraphicsItem*> & parts) {
10151017
* Updates and checks a diode. Checks that the power is less than the maximum power.
10161018
* @param[in] diode A part that is going to be checked and updated.
10171019
*/
1018-
void Simulator::updateDiode(ItemBase * diode) {
1020+
void Simulator::updateDiode(unsigned long timeStep, ItemBase * diode) {
10191021
double maxPower = getMaxPropValue(diode, "power");
1020-
double power = getPower(diode);
1022+
double power = getPower(timeStep, diode);
10211023
if (power > maxPower) {
10221024
drawSmoke(diode);
10231025
}
@@ -1028,15 +1030,15 @@ void Simulator::updateDiode(ItemBase * diode) {
10281030
* and updates the brightness of the LED in the breadboard view.
10291031
* @param[in] part An LED that is going to be checked and updated.
10301032
*/
1031-
void Simulator::updateLED(ItemBase * part) {
1033+
void Simulator::updateLED(unsigned long timeStep, ItemBase * part) {
10321034
LED* led = dynamic_cast<LED *>(part);
10331035
if (led) {
10341036
//Check if this an RGB led
10351037
QString rgbString = part->getProperty("rgb");
10361038

10371039
if (rgbString.isEmpty()) {
10381040
// Just one LED
1039-
double curr = getCurrent(part);
1041+
double curr = getCurrent(timeStep, part);
10401042
double maxCurr = getMaxPropValue(part, "current");
10411043

10421044
std::cout << "LED Current: " <<curr<<std::endl;
@@ -1050,9 +1052,9 @@ void Simulator::updateLED(ItemBase * part) {
10501052
}
10511053
} else {
10521054
// The part is an RGB LED
1053-
double currR = getCurrent(part, "R");
1054-
double currG = getCurrent(part, "G");
1055-
double currB = getCurrent(part, "B");
1055+
double currR = getCurrent(timeStep, part, "R");
1056+
double currG = getCurrent(timeStep, part, "G");
1057+
double currB = getCurrent(timeStep, part, "B");
10561058
double curr = std::max({currR, currG, currB});
10571059
double maxCurr = getMaxPropValue(part, "current");
10581060

@@ -1077,7 +1079,7 @@ void Simulator::updateLED(ItemBase * part) {
10771079
* and reverse voltage in electrolytic and tantalum capacitors (unidirectional capacitors).
10781080
* @param[in] part A capacitor that is going to be checked and updated.
10791081
*/
1080-
void Simulator::updateCapacitor(ItemBase * part) {
1082+
void Simulator::updateCapacitor(unsigned long timeStep, ItemBase * part) {
10811083
QString family = part->getProperty("family").toLower();
10821084

10831085
ConnectorItem * negLeg, * posLeg;
@@ -1090,7 +1092,7 @@ void Simulator::updateCapacitor(ItemBase * part) {
10901092
return;
10911093

10921094
double maxV = getMaxPropValue(part, "voltage");
1093-
double v = calculateVoltage(posLeg, negLeg);
1095+
double v = calculateVoltage(timeStep, posLeg, negLeg);
10941096
std::cout << "MaxVoltage of the capacitor: " << maxV << std::endl;
10951097
std::cout << "Capacitor voltage is : " << QString("%1").arg(v).toStdString() << std::endl;
10961098

@@ -1111,9 +1113,9 @@ void Simulator::updateCapacitor(ItemBase * part) {
11111113
* Updates and checks a resistor. Checks that the power is less than the maximum power.
11121114
* @param[in] part A resistor that is going to be checked and updated.
11131115
*/
1114-
void Simulator::updateResistor(ItemBase * part) {
1116+
void Simulator::updateResistor(unsigned long timeStep, ItemBase * part) {
11151117
double maxPower = getMaxPropValue(part, "power");
1116-
double power = getPower(part);
1118+
double power = getPower(timeStep, part);
11171119
std::cout << "Power: " << power <<std::endl;
11181120
if (power > maxPower) {
11191121
drawSmoke(part);
@@ -1125,10 +1127,10 @@ void Simulator::updateResistor(ItemBase * part) {
11251127
* for the two resistors "A" and "B".
11261128
* @param[in] part A potentiometer that is going to be checked and updated.
11271129
*/
1128-
void Simulator::updatePotentiometer(ItemBase * part) {
1130+
void Simulator::updatePotentiometer(unsigned long timeStep, ItemBase * part) {
11291131
double maxPower = getMaxPropValue(part, "power");
1130-
double powerA = getPower(part, "A"); //power through resistor A
1131-
double powerB = getPower(part, "B"); //power through resistor B
1132+
double powerA = getPower(timeStep, part, "A"); //power through resistor A
1133+
double powerB = getPower(timeStep, part, "B"); //power through resistor B
11321134
double power = powerA + powerB;
11331135
if (power > maxPower) {
11341136
drawSmoke(part);
@@ -1139,12 +1141,12 @@ void Simulator::updatePotentiometer(ItemBase * part) {
11391141
* Updates and checks a battery. Checks that there are no short circuits.
11401142
* @param[in] part A battery that is going to be checked and updated.
11411143
*/
1142-
void Simulator::updateBattery(ItemBase * part) {
1144+
void Simulator::updateBattery(unsigned long timeStep, ItemBase * part) {
11431145
double voltage = getMaxPropValue(part, "voltage");
11441146
double resistance = getMaxPropValue(part, "internal resistance");
11451147
double safetyMargin = 0.1; //TODO: This should be adjusted
11461148
double maxCurrent = voltage/resistance * safetyMargin;
1147-
double current = getCurrent(part); //current that the battery delivers
1149+
double current = getCurrent(timeStep, part); //current that the battery delivers
11481150
std::cout << "Battery: voltage=" << voltage << ", resistance=" << resistance <<std::endl;
11491151
std::cout << "Battery: MaxCurr=" << maxCurrent << ", Curr=" << current <<std::endl;
11501152
if (abs(current) > maxCurrent) {
@@ -1162,7 +1164,7 @@ bool Simulator::isSimulating()
11621164
* and that the current of the output is less than the maximum.
11631165
* @param[in] part A IR sensor that is going to be checked and updated.
11641166
*/
1165-
void Simulator::updateIRSensor(ItemBase * part) {
1167+
void Simulator::updateIRSensor(unsigned long timeStep, ItemBase * part) {
11661168
double maxV = getMaxPropValue(part, "voltage (max)");
11671169
double minV = getMaxPropValue(part, "voltage (min)");
11681170
double maxIout = getMaxPropValue(part, "max output current");
@@ -1184,16 +1186,16 @@ void Simulator::updateIRSensor(ItemBase * part) {
11841186
if(!gnd || !vcc || !out )
11851187
return;
11861188

1187-
double v = calculateVoltage(vcc, gnd); //voltage applied to the motor
1189+
double v = calculateVoltage(timeStep, vcc, gnd); //voltage applied to the motor
11881190
double i;
11891191
if (part->family().contains("line sensor")) {
11901192
//digital sensor (push-pull output)
11911193
QString spicename = part->instanceTitle().toLower();
11921194
spicename.prepend("q");
1193-
i = getTransistorCurrent(spicename, COLLECTOR); //voltage applied to the motor
1195+
i = getTransistorCurrent(timeStep, spicename, COLLECTOR); //voltage applied to the motor
11941196
} else {
11951197
//analogue sensor (modelled by a voltage source and a resistor)
1196-
i = getCurrent(part, "a"); //voltage applied to the motor
1198+
i = getCurrent(timeStep, part, "a"); //voltage applied to the motor
11971199
}
11981200
std::cout << "IR sensor Max Iout: " << maxIout << ", current Iout " << i << std::endl;
11991201
std::cout << "IR sensor Max V: " << maxV << ", current V " << v << std::endl;
@@ -1209,7 +1211,7 @@ void Simulator::updateIRSensor(ItemBase * part) {
12091211
* TODO: The number of arrows are proportional to the voltage applied.
12101212
* @param[in] part A DC motor that is going to be checked and updated.
12111213
*/
1212-
void Simulator::updateDcMotor(ItemBase * part) {
1214+
void Simulator::updateDcMotor(unsigned long timeStep, ItemBase * part) {
12131215
double maxV = getMaxPropValue(part, "voltage (max)");
12141216
double minV = getMaxPropValue(part, "voltage (min)");
12151217
std::cout << "Motor1: " << std::endl;
@@ -1222,7 +1224,7 @@ void Simulator::updateDcMotor(ItemBase * part) {
12221224
if(!terminal1 || !terminal2 )
12231225
return;
12241226

1225-
double v = calculateVoltage(terminal1, terminal2); //voltage applied to the motor
1227+
double v = calculateVoltage(timeStep, terminal1, terminal2); //voltage applied to the motor
12261228
if (abs(v) > maxV) {
12271229
drawSmoke(part);
12281230
return;
@@ -1279,7 +1281,7 @@ void Simulator::updateDcMotor(ItemBase * part) {
12791281
* Calculates the parameter to measure and updates the display of the multimeter.
12801282
* @param[in] part A multimeter that is going to be checked and updated.
12811283
*/
1282-
void Simulator::updateMultimeter(ItemBase * part) {
1284+
void Simulator::updateMultimeter(unsigned long timeStep, ItemBase * part) {
12831285
QString variant = part->getProperty("variant").toLower();
12841286
ConnectorItem * comProbe = nullptr, * vProbe = nullptr, * aProbe = nullptr;
12851287
QList<ConnectorItem *> probes = part->cachedConnectorItems();
@@ -1306,7 +1308,7 @@ void Simulator::updateMultimeter(ItemBase * part) {
13061308
}
13071309
if(comProbe->connectedToWires() && vProbe->connectedToWires()) {
13081310
std::cout << "Multimeter (v_dc) connected with two terminals. " << std::endl;
1309-
double v = calculateVoltage(vProbe, comProbe);
1311+
double v = calculateVoltage(timeStep, vProbe, comProbe);
13101312
updateMultimeterScreen(part, v);
13111313
}
13121314
return;
@@ -1317,7 +1319,7 @@ void Simulator::updateMultimeter(ItemBase * part) {
13171319
updateMultimeterScreen(part, "ERR");
13181320
return;
13191321
}
1320-
updateMultimeterScreen(part, getCurrent(part));
1322+
updateMultimeterScreen(part, getCurrent(timeStep, part));
13211323
return;
13221324
} else if (variant.compare("ohmmeter") == 0) {
13231325
std::cout << "Ohmmeter found. " << std::endl;
@@ -1326,8 +1328,8 @@ void Simulator::updateMultimeter(ItemBase * part) {
13261328
updateMultimeterScreen(part, "ERR");
13271329
return;
13281330
}
1329-
double v = calculateVoltage(vProbe, comProbe);
1330-
double a = getCurrent(part);
1331+
double v = calculateVoltage(timeStep, vProbe, comProbe);
1332+
double a = getCurrent(timeStep, part);
13311333
double r = abs(v/a);
13321334
std::cout << "Ohmmeter: Volt: " << v <<", Curr: " << a <<", Ohm: " << r << std::endl;
13331335
updateMultimeterScreen(part, r);
@@ -1340,7 +1342,7 @@ void Simulator::updateMultimeter(ItemBase * part) {
13401342
* Calculates the parameter to measure and updates the display of the multimeter.
13411343
* @param[in] part An oscilloscope that is going to be checked and updated.
13421344
*/
1343-
void Simulator::updateOscilloscope(ItemBase * part, int currTimeStep) {
1345+
void Simulator::updateOscilloscope(unsigned long timeStep, ItemBase * part) {
13441346
std::cout << "updateOscilloscope: " << std::endl;
13451347
ConnectorItem * comProbe = nullptr, * v1Probe = nullptr, * v2Probe = nullptr, * v3Probe = nullptr, * v4Probe = nullptr;
13461348
QList<ConnectorItem *> probes = part->cachedConnectorItems();
@@ -1423,7 +1425,7 @@ void Simulator::updateOscilloscope(ItemBase * part, int currTimeStep) {
14231425

14241426
//Draw the signal
14251427
QString pathId = QString("ch%1-path").arg(channel+1);
1426-
QString signalPath = generateSvgPath(v, vCom, currTimeStep, pathId, m_simStartTime, m_simStepTime, hPos, timeDiv, divisionSize/voltsDiv[channel], chOffsets[channel],
1428+
QString signalPath = generateSvgPath(v, vCom, timeStep, pathId, m_simStartTime, m_simStepTime, hPos, timeDiv, divisionSize/voltsDiv[channel], chOffsets[channel],
14271429
screenHeight, screenWidth, lineColor[channel], "20");
14281430
bbSvg += signalPath.arg(bbScreenOffsetX).arg(bbScreenOffsetY);
14291431
schSvg += signalPath.arg(schScreenOffsetX).arg(schScreenOffsetY);

src/simulation/simulator.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,25 @@ public slots:
6767
QChar getDeviceType (ItemBase*);
6868
double getMaxPropValue(ItemBase*, QString);
6969
QString getSymbol(ItemBase*, QString);
70-
double getVectorValueOrDefault(const std::string & vecName, double defaultValue);
71-
double calculateVoltage(ConnectorItem *, ConnectorItem *);
70+
double getVectorValueOrDefault(unsigned long timeStep, const std::string & vecName, double defaultValue);
71+
double calculateVoltage(unsigned long, ConnectorItem *, ConnectorItem *);
7272
std::vector<double> voltageVector(ConnectorItem *);
7373
QString generateSvgPath(std::vector<double>, std::vector<double>, int, QString, double, double, double, double, double, double, double, double, QString, QString);
74-
double getCurrent(ItemBase*, QString subpartName="");
75-
double getTransistorCurrent(QString spicePartName, TransistorLeg leg);
76-
double getPower(ItemBase*, QString subpartName="");
74+
double getCurrent(unsigned long, ItemBase*, QString subpartName="");
75+
double getTransistorCurrent(unsigned long timeStep, QString spicePartName, TransistorLeg leg);
76+
double getPower(unsigned long, ItemBase*, QString subpartName="");
7777

7878
//Functions to update the parts
79-
void updateCapacitor(ItemBase *);
80-
void updateDiode(ItemBase *);
81-
void updateLED(ItemBase *);
82-
void updateMultimeter(ItemBase *);
83-
void updateOscilloscope(ItemBase *, int);
84-
void updateResistor(ItemBase *);
85-
void updatePotentiometer(ItemBase *);
86-
void updateDcMotor(ItemBase *);
87-
void updateIRSensor(ItemBase *);
88-
void updateBattery(ItemBase *);
79+
void updateCapacitor(unsigned long, ItemBase *);
80+
void updateDiode(unsigned long, ItemBase *);
81+
void updateLED(unsigned long, ItemBase *);
82+
void updateMultimeter(unsigned long, ItemBase *);
83+
void updateOscilloscope(unsigned long, ItemBase *);
84+
void updateResistor(unsigned long, ItemBase *);
85+
void updatePotentiometer(unsigned long, ItemBase *);
86+
void updateDcMotor(unsigned long, ItemBase *);
87+
void updateIRSensor(unsigned long, ItemBase *);
88+
void updateBattery(unsigned long, ItemBase *);
8989

9090
bool m_simulating = false;
9191
MainWindow *m_mainWindow;

0 commit comments

Comments
 (0)