pumps now work properly, even if they are very manual :)
This commit is contained in:
parent
b8191cdf65
commit
d1e1da737f
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/scene-baked.glb (Stored with Git LFS)
BIN
assets/scene-baked.glb (Stored with Git LFS)
Binary file not shown.
BIN
assets/unbaked/scene.blend (Stored with Git LFS)
BIN
assets/unbaked/scene.blend (Stored with Git LFS)
Binary file not shown.
BIN
assets/unbaked/scene/labels.png (Stored with Git LFS)
BIN
assets/unbaked/scene/labels.png (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
|
||||
#include "fluid_holder.hpp"
|
||||
#include "../constants.hpp"
|
||||
#include "../util/constants.hpp"
|
||||
#include "../conversions/temperature.hpp"
|
||||
#include "../reactor/fuel/half_life.hpp"
|
||||
|
||||
|
@ -86,7 +86,7 @@ double fluid_holder::get_pressure() const
|
|||
|
||||
if(V == 0)
|
||||
{
|
||||
return NAN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (n * T * constants::R) / V;
|
||||
|
@ -95,7 +95,7 @@ double fluid_holder::get_pressure() const
|
|||
double fluid_holder::get_steam_density() const
|
||||
{
|
||||
double v = get_steam_volume();
|
||||
return v > 0 ? steam / v : NAN;
|
||||
return v > 0 ? steam / v : 0;
|
||||
}
|
||||
|
||||
void fluid_holder::update(double secs)
|
||||
|
|
|
@ -6,15 +6,20 @@
|
|||
|
||||
using namespace sim::coolant;
|
||||
|
||||
pump::pump(fluid_holder* src, fluid_holder* dst, double mass, double radius, double l_per_rev, double friction) :
|
||||
pump::pump(fluid_holder* src, fluid_holder* dst, double mass, double radius, double power, double l_per_rev, double friction) :
|
||||
src(src), dst(dst), mass(mass), radius(radius), l_per_rev(l_per_rev), friction(friction)
|
||||
{
|
||||
power = 1e8;
|
||||
this->power = power;
|
||||
}
|
||||
|
||||
double pump::get_flow() const
|
||||
{
|
||||
return src->fluid.l_to_g(l_per_rev * get_rpm() / 60);
|
||||
return l_per_rev * get_rpm() * 60;
|
||||
}
|
||||
|
||||
double pump::get_flow_mass() const
|
||||
{
|
||||
return src->fluid.l_to_g(get_flow());
|
||||
}
|
||||
|
||||
double pump::get_rpm() const
|
||||
|
@ -56,40 +61,38 @@ static double calc_work(double j, double mass)
|
|||
|
||||
void pump::update(double dt)
|
||||
{
|
||||
idling = false;
|
||||
|
||||
if(powered && !idling)
|
||||
{
|
||||
velocity += calc_work(dt * power, mass);
|
||||
}
|
||||
|
||||
fluid_holder fh_src(*src);
|
||||
fluid_holder fh_dst(*dst);
|
||||
|
||||
double src_heat = src->get_heat();
|
||||
double p_diff_1 = dst->get_pressure() - src->get_pressure();
|
||||
double src_volume = src->extract_fluid(get_flow() * dt);
|
||||
double dst_volume = dst->add_fluid(src_volume, src_heat);
|
||||
double src_volume = fh_src.extract_fluid(get_flow() * dt);
|
||||
double dst_volume = fh_dst.add_fluid(src_volume, src_heat);
|
||||
|
||||
if(dst_volume < src_volume)
|
||||
{
|
||||
src->add_fluid(src_volume - dst_volume, src_heat);
|
||||
}
|
||||
src->extract_fluid(dst_volume);
|
||||
dst->add_fluid(dst_volume, src_heat);
|
||||
|
||||
double p_diff_2 = dst->get_pressure() - src->get_pressure();
|
||||
double p_diff = (p_diff_1 + p_diff_2) / 2;
|
||||
double work = p_diff * dst_volume + get_rpm() * 60 * dt * friction;
|
||||
double work = p_diff * dst_volume * 0.001 + get_rpm() * 60 * dt * friction;
|
||||
|
||||
velocity -= calc_work(work, mass);
|
||||
|
||||
if(dst->get_level() > 400 || src->get_level() < 10)
|
||||
{
|
||||
idling = true;
|
||||
// idling = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
idling = false;
|
||||
// idling = false;
|
||||
}
|
||||
|
||||
std::cout << "RPM: " << get_rpm() << "\t";
|
||||
std::cout << "Flow: " << get_flow() << std::endl;
|
||||
std::cout << "Work Done: " << work << " J\n";
|
||||
std::cout << "Src Volume: " << src_volume << "\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,13 @@ class pump
|
|||
|
||||
public:
|
||||
|
||||
bool powered = true;
|
||||
bool powered = false;
|
||||
bool idling = false;
|
||||
|
||||
pump(fluid_holder* src, fluid_holder* dst, double mass, double radius, double l_per_rev, double friction);
|
||||
pump(fluid_holder* src, fluid_holder* dst, double mass, double radius, double power, double l_per_rev, double friction);
|
||||
|
||||
double get_flow() const; // g/s
|
||||
double get_flow() const; // L/s
|
||||
double get_flow_mass() const; // g/s
|
||||
double get_rpm() const; // rev/min
|
||||
|
||||
const char* get_state_string();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#include "valve.hpp"
|
||||
#include "../conversions/temperature.hpp"
|
||||
#include "../constants.hpp"
|
||||
#include "../util/constants.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
|
|
@ -73,16 +73,14 @@ struct core_monitor : public focus::focus_t
|
|||
|
||||
struct core_joystick : public focus::focus_t
|
||||
{
|
||||
double ypos = 0;
|
||||
|
||||
virtual void on_cursor_pos(double x, double y)
|
||||
{
|
||||
ypos += y;
|
||||
sim::system::active.reactor->add_rod_speed(y * 1e-6);
|
||||
}
|
||||
|
||||
virtual void update(double dt)
|
||||
virtual ~core_joystick()
|
||||
{
|
||||
sim::system::active.reactor->add_rod_speed(ypos * dt * 1e-6);
|
||||
sim::system::active.reactor->reset_rod_speed();
|
||||
}
|
||||
|
||||
virtual void on_mouse_button(int button, int action, int mods)
|
||||
|
|
|
@ -54,6 +54,15 @@ primary_loop::primary_loop()
|
|||
|
||||
}
|
||||
|
||||
void primary_loop::toggle_primary_pump()
|
||||
{
|
||||
system& sys = sim::system::active;
|
||||
bool state;
|
||||
|
||||
sys.primary_pump->powered = state = !sys.primary_pump->powered;
|
||||
gm_switch_primary.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, state ? 0.07 : 0, 0));
|
||||
}
|
||||
|
||||
void primary_loop::init()
|
||||
{
|
||||
mesh1.model_matrix = locations::monitors[3];
|
||||
|
@ -85,8 +94,18 @@ void primary_loop::init()
|
|||
mesh1.bind();
|
||||
mesh1.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "primary_coolant_pump_switch.glb");
|
||||
gm_switch_primary.bind();
|
||||
gm_switch_primary.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "secondary_coolant_pump_switch.glb");
|
||||
gm_switch_secondary.bind();
|
||||
gm_switch_secondary.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
m_joystick_turbine_bypass.load_model("../assets/model", "turbine_valve_bypass_joystick.stl");
|
||||
m_joystick_turbine_inlet.load_model("../assets/model", "turbine_valve_inlet_joystick.stl");
|
||||
m_switch_primary.load_model("../assets/model", "primary_coolant_pump_switch.stl");
|
||||
m_switch_secondary.load_model("../assets/model", "secondary_coolant_pump_switch.stl");
|
||||
}
|
||||
|
||||
void primary_loop::update()
|
||||
|
@ -104,7 +123,7 @@ void primary_loop::update()
|
|||
ss << "\n\n\n";
|
||||
ss << sys.primary_pump->get_state_string() << "\n";
|
||||
ss << show( sys.primary_pump->get_rpm() ) << " r/min\n";
|
||||
ss << show( sys.primary_pump->get_flow() / 1000 ) << " kg/s\n";
|
||||
ss << show( sys.primary_pump->get_flow_mass() / 1000 ) << " kg/s\n";
|
||||
ss << "\n\n\n";
|
||||
ss << show( sys.condenser->get_heat() ) << " C\n";
|
||||
ss << show( sys.condenser->get_steam() ) << " g\n";
|
||||
|
@ -119,6 +138,8 @@ void primary_loop::update()
|
|||
focus::set(std::make_unique<valve_joystick>(sys.turbine_bypass_valve.get()));
|
||||
if(m_joystick_turbine_inlet.check_focus())
|
||||
focus::set(std::make_unique<valve_joystick>(sys.turbine_inlet_valve.get()));
|
||||
if(m_switch_primary.check_focus())
|
||||
toggle_primary_pump();
|
||||
}
|
||||
|
||||
void primary_loop::render()
|
||||
|
@ -130,5 +151,13 @@ void primary_loop::render()
|
|||
mesh2.bind();
|
||||
mesh2.uniform();
|
||||
mesh2.render();
|
||||
|
||||
gm_switch_primary.bind();
|
||||
gm_switch_primary.uniform();
|
||||
gm_switch_primary.render();
|
||||
|
||||
gm_switch_secondary.bind();
|
||||
gm_switch_secondary.uniform();
|
||||
gm_switch_secondary.render();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,15 @@ class primary_loop
|
|||
{
|
||||
sim::graphics::glmesh mesh1, mesh2;
|
||||
|
||||
sim::graphics::glmesh gm_switch_primary;
|
||||
sim::graphics::glmesh gm_switch_secondary;
|
||||
|
||||
sim::graphics::mesh m_joystick_turbine_bypass;
|
||||
sim::graphics::mesh m_joystick_turbine_inlet;
|
||||
sim::graphics::mesh m_switch_primary;
|
||||
sim::graphics::mesh m_switch_secondary;
|
||||
|
||||
void toggle_primary_pump();
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#include "vessel.hpp"
|
||||
#include "../../constants.hpp"
|
||||
#include "../../util/constants.hpp"
|
||||
#include "../../conversions/temperature.hpp"
|
||||
#include "../fuel/half_life.hpp"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#include "reactor.hpp"
|
||||
#include "../random.hpp"
|
||||
#include "../util/random.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
|
@ -37,12 +37,12 @@ system::system()
|
|||
|
||||
vessel = std::make_unique<reactor::coolant::vessel>(sim::coolant::WATER, 8, 10, 6e6, 300);
|
||||
reactor = std::make_unique<reactor::reactor>(sim::reactor::builder(19, 19, 1.0 / 4.0, 4, reactor::fuel::fuel_rod(0.5), vessel.get(), layout));
|
||||
condenser = std::make_unique<coolant::condenser>(sim::coolant::WATER, 8, 6, 3e6, 0);
|
||||
condenser = std::make_unique<coolant::condenser>(sim::coolant::WATER, 8, 6, 3e6, 200);
|
||||
turbine = std::make_unique<electric::turbine>(sim::coolant::WATER, condenser.get(), 6, 3, 2e6);
|
||||
|
||||
turbine_inlet_valve = std::make_unique<coolant::valve>(vessel.get(), turbine.get(), 0, 1e-2);
|
||||
turbine_bypass_valve = std::make_unique<coolant::valve>(vessel.get(), condenser.get(), 0, 1e-2);
|
||||
primary_pump = std::make_unique<coolant::pump>(condenser.get(), vessel.get(), 1e6, 1, 1, 0);
|
||||
primary_pump = std::make_unique<coolant::pump>(condenser.get(), vessel.get(), 1e6, 1, 1e6, 1, 10);
|
||||
}
|
||||
|
||||
system::system(system&& o)
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* Copyright 2019 Bradley J. Snyder <snyder.bradleyj@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "pid.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PIDImpl
|
||||
{
|
||||
public:
|
||||
PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki );
|
||||
~PIDImpl();
|
||||
double calculate( double setpoint, double pv );
|
||||
|
||||
private:
|
||||
double _dt;
|
||||
double _max;
|
||||
double _min;
|
||||
double _Kp;
|
||||
double _Kd;
|
||||
double _Ki;
|
||||
double _pre_error;
|
||||
double _integral;
|
||||
};
|
||||
|
||||
|
||||
PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki )
|
||||
{
|
||||
pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki);
|
||||
}
|
||||
double PID::calculate( double setpoint, double pv )
|
||||
{
|
||||
return pimpl->calculate(setpoint,pv);
|
||||
}
|
||||
PID::~PID()
|
||||
{
|
||||
delete pimpl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki ) :
|
||||
_dt(dt),
|
||||
_max(max),
|
||||
_min(min),
|
||||
_Kp(Kp),
|
||||
_Kd(Kd),
|
||||
_Ki(Ki),
|
||||
_pre_error(0),
|
||||
_integral(0)
|
||||
{
|
||||
}
|
||||
|
||||
double PIDImpl::calculate( double setpoint, double pv )
|
||||
{
|
||||
|
||||
// Calculate error
|
||||
double error = setpoint - pv;
|
||||
|
||||
// Proportional term
|
||||
double Pout = _Kp * error;
|
||||
|
||||
// Integral term
|
||||
_integral += error * _dt;
|
||||
double Iout = _Ki * _integral;
|
||||
|
||||
// Derivative term
|
||||
double derivative = (error - _pre_error) / _dt;
|
||||
double Dout = _Kd * derivative;
|
||||
|
||||
// Calculate total output
|
||||
double output = Pout + Iout + Dout;
|
||||
|
||||
// Restrict to max/min
|
||||
if( output > _max )
|
||||
output = _max;
|
||||
else if( output < _min )
|
||||
output = _min;
|
||||
|
||||
// Save error to previous error
|
||||
_pre_error = error;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
PIDImpl::~PIDImpl()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Copyright 2019 Bradley J. Snyder <snyder.bradleyj@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class PIDImpl;
|
||||
class PID
|
||||
{
|
||||
public:
|
||||
// Kp - proportional gain
|
||||
// Ki - Integral gain
|
||||
// Kd - derivative gain
|
||||
// dt - loop interval time
|
||||
// max - maximum value of manipulated variable
|
||||
// min - minimum value of manipulated variable
|
||||
PID( double dt, double max, double min, double Kp, double Kd, double Ki );
|
||||
|
||||
// Returns the manipulated variable given a setpoint and current process value
|
||||
double calculate( double setpoint, double pv );
|
||||
~PID();
|
||||
|
||||
private:
|
||||
PIDImpl *pimpl;
|
||||
};
|
||||
|
Loading…
Reference in New Issue