/*Update the PID output, called in some loop where newPoint is updated */ void update(){ /* Update timer */ timer+=millis(); /* Update error, difference between setpoint and newpoint. */ error = (*setPoint - *newPoint); /* If dt time has passed, apply PID */ if(timer>= dt){ /* The value of the out is updated */ *output = proportional() + integrator() + derivative(); /* timer is decreased by dt, timer MIGHT be 1.5 dt so we can't start counting at 0 again */ timer -= dt; /* Constrain the PID output */ if(*output>PID_MAX) *output = PID_MAX; if(*output<PID_MIN) *output = PID_MIN; } prevPoint = *newPoint; prevError = error; }
QWidget *float2_param_t::do_create_widgets() { QWidget *top = new QWidget(); QrLabel *label = new QrLabel( top); input0_ = new QrDoubleSpinBox( top); input1_ = new QrDoubleSpinBox( top); QSize s = input0_->sizeHint(); label->move( 0, 0); label->resize( ui::inspector_t::Instance().left_margin() - 5, s.height()); label->setAlignment( Qt::AlignRight | Qt::AlignVCenter); label->setText( name().c_str()); int xpos = ui::inspector_t::Instance().left_margin(); float low = absolute_min(); float high = absolute_max(); Imath::V2f v = relative_to_absolute( get_value<Imath::V2f>( *this)); input0_->move( xpos, 0); input0_->resize( s.width(), s.height()); input0_->setRange( low, high); input0_->setStep( step()); input0_->setValue( v.x); input0_->setEnabled( enabled()); connect( input0_, SIGNAL( calculatorValueChanged( double)), this, SLOT( value_changed( double))); connect( input0_, SIGNAL( spinBoxPressed()), this, SLOT( spinbox_pressed())); connect( input0_, SIGNAL( spinBoxMoved( double)), this, SLOT( spinbox_moved( double))); connect( input0_, SIGNAL( spinBoxReleased()), this, SLOT( spinbox_released())); xpos += ( s.width() + 5); input1_->move( xpos, 0); input1_->resize( s.width(), s.height()); input1_->setRange( low, high); input1_->setStep( step()); input1_->setValue( v.y); input1_->setEnabled( enabled()); connect( input1_, SIGNAL( calculatorValueChanged( double)), this, SLOT( value_changed( double))); connect( input1_, SIGNAL( spinBoxPressed()), this, SLOT( spinbox_pressed())); connect( input1_, SIGNAL( spinBoxMoved( double)), this, SLOT( spinbox_moved( double))); connect( input1_, SIGNAL( spinBoxReleased()), this, SLOT( spinbox_released())); xpos += ( s.width() + 2); if( proportional()) { create_proportional_button( top); if( prop_button_) prop_button_->move( xpos, 0); } top->setMinimumSize( ui::inspector_t::Instance().width(), s.height()); top->setMaximumSize( ui::inspector_t::Instance().width(), s.height()); top->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed); return top; }
T PID<T>::calculate(T val) { T v = val - (feedback + setpoint); T p,i,d; #ifdef P_CONTROL p = proportional(v); #endif #ifdef I_CONTROL i = integral(v); #endif #ifdef D_CONTROL d = derivative(v); #endif return p + i + d; }
/* * Parse through the fontlist data and set up the three scroll lists. The fix * parameter can be used to exclude a list from any changes. This is used for * updates after selections caused by the users actions. */ static void fill_lists(enum ListSpecifier fix, SharedFontSelData *data) { char *list[NONE][MAX_ENTRIES_IN_LIST]; int count[NONE]; char buf[TEMP_BUF_SIZE]; XmString items[MAX_ENTRIES_IN_LIST]; int i; int idx; for (idx = (int)ENCODING; idx < (int)NONE; ++idx) count[idx] = 0; /* First we insert the wild char into every single list. */ if (fix != ENCODING) add_to_list(list[ENCODING], wild, &count[ENCODING]); if (fix != NAME) add_to_list(list[NAME], wild, &count[NAME]); if (fix != STYLE) add_to_list(list[STYLE], wild, &count[STYLE]); if (fix != SIZE) add_to_list(list[SIZE], wild, &count[SIZE]); for (i = 0; i < data->num && i < MAX_ENTRIES_IN_LIST; i++) { if (proportional(fn(data, i))) continue; if (fix != ENCODING && match(data, NAME, i) && match(data, STYLE, i) && match(data, SIZE, i)) { encoding_part(fn(data, i), buf); add_to_list(list[ENCODING], buf, &count[ENCODING]); } if (fix != NAME && match(data, ENCODING, i) && match(data, STYLE, i) && match(data, SIZE, i)) { name_part(fn(data, i), buf); add_to_list(list[NAME], buf, &count[NAME]); } if (fix != STYLE && match(data, ENCODING, i) && match(data, NAME, i) && match(data, SIZE, i)) { style_part(fn(data, i), buf); add_to_list(list[STYLE], buf, &count[STYLE]); } if (fix != SIZE && match(data, ENCODING, i) && match(data, NAME, i) && match(data, STYLE, i)) { size_part(fn(data, i), buf, data->in_pixels); add_to_list(list[SIZE], buf, &count[SIZE]); } } /* * And now do the preselection in all lists where there was one: */ if (fix != ENCODING) { Cardinal n_items; WidgetList children; Widget selected_button = 0; /* Get and update the current button list. */ XtVaGetValues(data->encoding_pulldown, XmNchildren, &children, XmNnumChildren, &n_items, NULL); for (i = 0; i < count[ENCODING]; ++i) { Widget button; items[i] = XmStringCreateLocalized(list[ENCODING][i]); if (i < (int)n_items) { /* recycle old button */ XtVaSetValues(children[i], XmNlabelString, items[i], XmNuserData, i, NULL); button = children[i]; } else { /* create a new button */ button = XtVaCreateManagedWidget("button", xmPushButtonGadgetClass, data->encoding_pulldown, XmNlabelString, items[i], XmNuserData, i, NULL); XtAddCallback(button, XmNactivateCallback, (XtCallbackProc) encoding_callback, (XtPointer) data); XtManageChild(button); } if (data->sel[ENCODING]) { if (!strcmp(data->sel[ENCODING], list[ENCODING][i])) selected_button = button; } XtFree(list[ENCODING][i]); } /* Destroy all the outstanding menu items. */ for (i = count[ENCODING]; i < (int)n_items; ++i) { XtUnmanageChild(children[i]); XtDestroyWidget(children[i]); } /* Preserve the current selection visually. */ if (selected_button) { XtVaSetValues(data->encoding_menu, XmNmenuHistory, selected_button, NULL); } for (i = 0; i < count[ENCODING]; ++i) XmStringFree(items[i]); } /* * Now loop trough the remaining lists and set them up. */ for (idx = (int)NAME; idx < (int)NONE; ++idx) { Widget w; if (fix == (enum ListSpecifier)idx) continue; switch ((enum ListSpecifier)idx) { case NAME: w = data->list[NAME]; break; case STYLE: w = data->list[STYLE]; break; case SIZE: w = data->list[SIZE]; break; default: w = (Widget)0; /* for lint */ } for (i = 0; i < count[idx]; ++i) { items[i] = XmStringCreateLocalized(list[idx][i]); XtFree(list[idx][i]); } XmListDeleteAllItems(w); XmListAddItems(w, items, count[idx], 1); if (data->sel[idx]) { XmStringFree(items[0]); items[0] = XmStringCreateLocalized(data->sel[idx]); XmListSelectItem(w, items[0], False); XmListSetBottomItem(w, items[0]); } for (i = 0; i < count[idx]; ++i) XmStringFree(items[i]); } }
double PID::getPID(double error){ double value = proportional(error) + integral(error) + derivative(error); return trim(value); }
double PID::getP(double error){ return trim(proportional(error)); }