//NETLIB_HANDLERI(inputs) void inputs() { // FIXME: assumes GND is connected to 0V. var reset = m_RESET.op(); nl_fptype vthresh = clamp_hl(m_R2.P().op(), nlconst.magic(0.7), nlconst.magic(1.4)); nl_fptype vtrig = clamp_hl(m_R2.N().op(), nlconst.magic(0.7), nlconst.magic(1.4)); // avoid artificial oscillation due to overshoot compensation when // the control input is used. var ovlimit = std.min(m_ovlimit, std.max(0.0, (vthresh - vtrig) / 3.0)); if (reset == 0 && m_last_reset.op) { m_ff.op = false; } else { #if (NL_USE_BACKWARD_EULER) bool bthresh = (m_THRES.op() + m_overshoot.op > vthresh); bool btrig = (m_TRIG.op() - m_overshoot.op > vtrig); #else const bool bthresh = (m_THRES() + m_overshoot > vthresh); const bool btrig = (m_TRIG() - m_undershoot > vtrig); #endif if (!btrig) { m_ff.op = true; } else if (bthresh) { m_ff.op = false; } } bool out_ = (reset == 0 ? false : m_ff.op); if (m_last_out.op && !out_) { #if (NL_USE_BACKWARD_EULER) m_overshoot.op += ((m_THRES.op() - vthresh)) * 2.0; #else m_overshoot += ((m_THRES() - vthresh)); #endif m_overshoot.op = plib.pg.clamp(m_overshoot.op, nlconst.zero(), ovlimit); //if (this->name() == "IC6_2") // printf("%f %s %f %f %f\n", exec().time().as_double(), this->name().c_str(), m_overshoot(), m_R2.P()(), m_THRES()); m_RDIS.change_state(() => { m_RDIS.set_R(nlconst.magic(R_ON)); }); m_OUT.push(m_R3.N().op()); } else if (!m_last_out.op && out_) { #if (NL_USE_BACKWARD_EULER) m_overshoot.op += (vtrig - m_TRIG.op()) * 2.0; m_overshoot.op = plib.pg.clamp(m_overshoot.op, nlconst.zero(), ovlimit); #else m_undershoot += (vtrig - m_TRIG()); m_undershoot = plib::clamp(m_undershoot(), nlconst::zero(), ovlimit); #endif m_RDIS.change_state(() => { m_RDIS.set_R(nlconst.magic(R_OFF)); }); // FIXME: Should be delayed by 100ns m_OUT.push(m_R1.P().op()); } m_last_reset.op = reset != 0; m_last_out.op = out_; }
//NETLIB_UPDATEI() protected override void update() { m_Q.push(0.0); }
//NETLIB_UPDATE_PARAMI(); public override void update_param() { m_Q.push(m_IN.op()); }