20#define TAB_VARIABLES 6
25#define POSITION_SCALE 3
26#define POSITION_MAXOUTPUT 4
27#define POSITION_MAXINT 5
28#define POSITION_OFFSET 6
29#define POSITION_STICTIONUP 7
30#define POSITION_STICTIONDW 8
35#define VELOCITY_SCALE 3
36#define VELOCITY_MAXOUTPUT 4
37#define VELOCITY_MAXINT 5
38#define VELOCITY_OFFSET 6
39#define VELOCITY_STICTIONUP 7
40#define VELOCITY_STICTIONDW 8
46#define TORQUE_MAXOUTPUT 4
47#define TORQUE_MAXINT 5
48#define TORQUE_OFFSET 6
49#define TORQUE_STITCTIONUP 7
50#define TORQUE_STICTIONDW 8
52#define TORQUE_BEMFGAIN 10
53#define TORQUE_BEMFSCALE 11
54#define TORQUE_KTAUGAIN 12
55#define TORQUE_KTAUSCALE 13
56#define TORQUE_VISCOUSPOS 14
57#define TORQUE_VISCOUSNEG 15
58#define TORQUE_COULOMBPOS 16
59#define TORQUE_COULOMBNEG 17
60#define VELOCITY_THRESHOLD 18
65#define CURRENT_SCALE 3
66#define CURRENT_MAXOUTPUT 4
67#define CURRENT_MAXINT 5
68#define CURRENT_OFFSET 6
70PidDlg::PidDlg(QString partname,
int jointIndex, QString jointName, QWidget *parent) :
76 this->jointIndex = jointIndex;
78 QString title = QString(
"Pid Control %1 JNT:%2 (%3)").arg(partname).arg(jointIndex).arg(jointName);
79 setWindowTitle(title);
81 connect(ui->btnRefresh,
SIGNAL(clicked()),
this, SLOT(onRefresh()));
82 connect(ui->btnSend,
SIGNAL(clicked()),
this,SLOT(onSend()));
83 connect(ui->btnCancel,
SIGNAL(clicked()),
this,SLOT(onCancel()));
84 connect(ui->btnDump,
SIGNAL(clicked()),
this, SLOT(onDumpRemoteVariables()));
86 connect(ui->tableStiffness, &QTableWidget::itemChanged,
this, [
this](QTableWidgetItem* item)
88 if (item == ui->tableStiffness->item(2, 3))
90 onForceOffsetChanged(item->text());
103void PidDlg::onForceOffsetChanged(QString forceOffset)
105 forceOffsetChanged =
true;
108void PidDlg::onDumpRemoteVariables()
115 for (
auto& button : buttons)
126 ui->tablePosition->item(
POSITION_KP,0)->setText(QString(
"%1").arg((
double)myPid.
kp));
127 ui->tablePosition->item(
POSITION_KP,1)->setText(QString(
"%1").arg((
double)myPid.
kp));
129 ui->tablePosition->item(
POSITION_KD,0)->setText(QString(
"%1").arg((
double)myPid.
kd));
130 ui->tablePosition->item(
POSITION_KD,1)->setText(QString(
"%1").arg((
double)myPid.
kd));
132 ui->tablePosition->item(
POSITION_KI,0)->setText(QString(
"%1").arg((
double)myPid.
ki));
133 ui->tablePosition->item(
POSITION_KI,1)->setText(QString(
"%1").arg((
double)myPid.
ki));
156 ui->tableVelocity->item(
VELOCITY_KP, 0)->setText(QString(
"%1").arg((
double)myPid.
kp));
157 ui->tableVelocity->item(
VELOCITY_KP, 1)->setText(QString(
"%1").arg((
double)myPid.
kp));
159 ui->tableVelocity->item(
VELOCITY_KD, 0)->setText(QString(
"%1").arg((
double)myPid.
kd));
160 ui->tableVelocity->item(
VELOCITY_KD, 1)->setText(QString(
"%1").arg((
double)myPid.
kd));
162 ui->tableVelocity->item(
VELOCITY_KI, 0)->setText(QString(
"%1").arg((
double)myPid.
ki));
163 ui->tableVelocity->item(
VELOCITY_KI, 1)->setText(QString(
"%1").arg((
double)myPid.
ki));
186 ui->tableTorque->item(
TORQUE_KP,0)->setText(QString(
"%1").arg((
double)myPid.
kp));
187 ui->tableTorque->item(
TORQUE_KP,1)->setText(QString(
"%1").arg((
double)myPid.
kp));
189 ui->tableTorque->item(
TORQUE_KFF,0)->setText(QString(
"%1").arg((
double)myPid.
kff));
190 ui->tableTorque->item(
TORQUE_KFF,1)->setText(QString(
"%1").arg((
double)myPid.
kff));
192 ui->tableTorque->item(
TORQUE_KD,0)->setText(QString(
"%1").arg((
double)myPid.
kd));
193 ui->tableTorque->item(
TORQUE_KD,1)->setText(QString(
"%1").arg((
double)myPid.
kd));
195 ui->tableTorque->item(
TORQUE_BEMFGAIN,0)->setText(QString(
"%1").arg((
double)TrqParam.
bemf));
196 ui->tableTorque->item(
TORQUE_BEMFGAIN,1)->setText(QString(
"%1").arg((
double)TrqParam.
bemf));
201 ui->tableTorque->item(
TORQUE_KTAUGAIN,0)->setText(QString(
"%1").arg((
double)TrqParam.
ktau));
202 ui->tableTorque->item(
TORQUE_KTAUGAIN,1)->setText(QString(
"%1").arg((
double)TrqParam.
ktau));
220 ui->tableTorque->item(
TORQUE_KI,0)->setText(QString(
"%1").arg((
double)myPid.
ki));
221 ui->tableTorque->item(
TORQUE_KI,1)->setText(QString(
"%1").arg((
double)myPid.
ki));
223 ui->tableTorque->item(
TORQUE_SCALE,0)->setText(QString(
"%1").arg((
int)myPid.
scale));
224 ui->tableTorque->item(
TORQUE_SCALE,1)->setText(QString(
"%1").arg((
int)myPid.
scale));
242void PidDlg::onSendRemoteVariable()
245 for (
size_t elem = 0; elem < buttons.size(); elem++)
247 if (sender() == buttons[elem])
257 std::string key = ui->tableVariables->item(i, 0)->text().toStdString();
258 std::string val = ui->tableVariables->item(i, 1)->text().toStdString();
269 ui->tableVariables->clear();
270 ui->tableVariables->clearContents();
271 ui->tableVariables->setRowCount(0);
272 ui->tableVariables->setColumnCount(0);
273 ui->tableVariables->insertColumn(0);
274 ui->tableVariables->insertColumn(0);
275 ui->tableVariables->insertColumn(0);
276 ui->tableVariables->setMinimumWidth(500);
277 ui->tableVariables->setHorizontalHeaderItem(0,
new QTableWidgetItem(QString(
"Key")));
278 ui->tableVariables->setHorizontalHeaderItem(1,
new QTableWidgetItem(QString(
"Values")));
279 ui->tableVariables->setHorizontalHeaderItem(2,
new QTableWidgetItem(QString(
"")));
285 int keys_size = keys.
size();
286 for (
auto& button : buttons)
292 buttons.resize(keys_size);
294 for (
int i = 0; i < keys_size; i++)
296 buttons[i] =
new QPushButton(
"Send");
297 connect(buttons[i],
SIGNAL(clicked()),
this, SLOT(onSendRemoteVariable()));
305 ui->tableVariables->insertRow(i);
306 ui->tableVariables->setItem(i, 0,
new QTableWidgetItem(QString(v.c_str())));
307 ui->tableVariables->item(i, 0)->setFlags(Qt::NoItemFlags);
308 ui->tableVariables->setItem(i, 1,
new QTableWidgetItem(QString(val.
toString().c_str())));
309 ui->tableVariables->item(i, 1)->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled );
310 ui->tableVariables->setColumnWidth(1, 500);
311 ui->tableVariables->setCellWidget(i, 2, (QWidget*)buttons[i]);
331 double curDampVal,
double minDamp,
double maxDamp)
333 ui->tableStiffness->item(0,0)->setText(QString(
"%L1").arg(curStiffVal,0,
'f',3));
334 ui->tableStiffness->item(0,1)->setText(QString(
"%L1").arg(minStiff,0,
'f',3));
335 ui->tableStiffness->item(0,2)->setText(QString(
"%L1").arg(maxStiff,0,
'f',3));
336 ui->tableStiffness->item(0,3)->setText(QString(
"%L1").arg(curStiffVal,0,
'f',3));
338 ui->tableStiffness->item(1,0)->setText(QString(
"%L1").arg(curDampVal,0,
'f',3));
339 ui->tableStiffness->item(1,1)->setText(QString(
"%L1").arg(minDamp,0,
'f',3));
340 ui->tableStiffness->item(1,2)->setText(QString(
"%L1").arg(maxDamp,0,
'f',3));
341 ui->tableStiffness->item(1,3)->setText(QString(
"%L1").arg(curDampVal,0,
'f',3));
346 ui->tableStiffness->item(2,0)->setText(QString(
"%L1").arg(curForceVal,0,
'f',3));
347 ui->tableStiffness->item(2,1)->setText(QString(
"%L1").arg(minForce,0,
'f',3));
348 ui->tableStiffness->item(2,2)->setText(QString(
"%L1").arg(maxForce,0,
'f',3));
349 ui->tableStiffness->item(2,3)->setText(QString(
"%L1").arg(curForceVal,0,
'f',3));
350 forceOffsetChanged=
false;
356 ui->tablePWM->item(0, 0)->setText(QString(
"%1").arg((
double)PWMVal));
357 ui->tablePWM->item(0, 1)->setText(QString(
"%1").arg((
double)PWMVal));
359 ui->tablePWM->item(1,0)->setText(QString(
"%1").arg(pwm));
364 ui->tableCurrent->item(
CURRENT_KP, 0)->setText(QString(
"%1").arg((
double)myPid.
kp));
365 ui->tableCurrent->item(
CURRENT_KP, 1)->setText(QString(
"%1").arg((
double)myPid.
kp));
367 ui->tableCurrent->item(
CURRENT_KD, 0)->setText(QString(
"%1").arg((
double)myPid.
kd));
368 ui->tableCurrent->item(
CURRENT_KD, 1)->setText(QString(
"%1").arg((
double)myPid.
kd));
370 ui->tableCurrent->item(
CURRENT_KI, 0)->setText(QString(
"%1").arg((
double)myPid.
ki));
371 ui->tableCurrent->item(
CURRENT_KI, 1)->setText(QString(
"%1").arg((
double)myPid.
ki));
373 ui->tableCurrent->item(
CURRENT_SCALE, 0)->setText(QString(
"%1").arg((
int)myPid.
scale));
374 ui->tableCurrent->item(
CURRENT_SCALE, 1)->setText(QString(
"%1").arg((
int)myPid.
scale));
386void PidDlg::onRefresh()
396 switch (ui->tabMain->currentIndex()) {
398 newPid.
kp = ui->tablePosition->item(
POSITION_KP,1)->text().toDouble();
399 newPid.
kd = ui->tablePosition->item(
POSITION_KD,1)->text().toDouble();
400 newPid.
ki = ui->tablePosition->item(
POSITION_KI,1)->text().toDouble();
410 newPid.
kp = ui->tableVelocity->item(
VELOCITY_KP, 1)->text().toDouble();
411 newPid.
kd = ui->tableVelocity->item(
VELOCITY_KD, 1)->text().toDouble();
412 newPid.
ki = ui->tableVelocity->item(
VELOCITY_KI, 1)->text().toDouble();
422 newPid.
kp = ui->tableTorque->item(
TORQUE_KP,1)->text().toDouble();
423 newPid.
kff = ui->tableTorque->item(
TORQUE_KFF,1)->text().toDouble();
424 newPid.
kd = ui->tableTorque->item(
TORQUE_KD,1)->text().toDouble();
434 newPid.
ki = ui->tableTorque->item(
TORQUE_KI,1)->text().toDouble();
444 double desiredStiff = ui->tableStiffness->item(0,3)->text().toDouble();
445 double desiredDamp = ui->tableStiffness->item(1,3)->text().toDouble();
446 double desiredForce = ui->tableStiffness->item(2,3)->text().toDouble();
448 if (forceOffsetChanged)
451 forceOffsetChanged =
false;
456 int desiredDuty = ui->tablePWM->item(0,1)->text().toDouble();
457 emit
sendPWM(jointIndex,desiredDuty);
461 newPid.
kp = ui->tableCurrent->item(
CURRENT_KP, 1)->text().toDouble();
462 newPid.
kd = ui->tableCurrent->item(
CURRENT_KD, 1)->text().toDouble();
463 newPid.
ki = ui->tableCurrent->item(
CURRENT_KI, 1)->text().toDouble();
473 int rows = ui->tableVariables->rowCount();
474 for (
int i = 0; i < rows; i++)
476 std::string key = ui->tableVariables->item(i, 0)->text().toStdString();
477 std::string val = ui->tableVariables->item(i, 1)->text().toStdString();
491void PidDlg::onCancel()
int SIGNAL(int pid, int signum)
void sendTorquePid(int jointIndex, Pid, MotorTorqueParameters newTorqueParam)
void initVelocity(Pid myPid)
void sendForceOffset(int, double)
void sendVelocityPid(int jointIndex, Pid pid)
void refreshPids(int jointIndex)
void initPosition(Pid myPid)
void sendSingleRemoteVariable(std::string key, yarp::os::Bottle val)
void sendPWM(int jointIndex, double dutyVal)
void updateAllRemoteVariables()
void initTorque(Pid myPid, MotorTorqueParameters TorqueParam)
void initTorqueOffset(double curForceVal, double minForce, double maxForce)
void initCurrent(Pid myPid)
void sendStiffness(int, double, double)
void initStiffness(double curStiffVal, double minStiff, double maxStiff, double curDampVal, double minDamp, double maxDamp)
void initRemoteVariables(IRemoteVariables *iVar)
PidDlg(QString partname, int jointIndex, QString jointName, QWidget *parent=0)
void dumpRemoteVariables()
void initPWM(double pwmVal, double pwm)
void sendPositionPid(int jointIndex, Pid pid)
void sendCurrentPid(int jointIndex, Pid pid)
IRemoteVariables interface.
virtual bool getRemoteVariable(std::string key, yarp::os::Bottle &val)=0
virtual bool getRemoteVariablesList(yarp::os::Bottle *listOfKeys)=0
Contains the parameters for a PID.
double scale
scale for the pid output
double offset
pwm offset added to the pid output
double stiction_down_val
down stiction offset added to the pid output
double stiction_up_val
up stiction offset added to the pid output
double max_output
max output
double kff
feedforward gain
double ki
integrative gain
double max_int
saturation threshold for the integrator
double kp
proportional gain
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
virtual bool isString() const
Checks if value is a string.
virtual std::string asString() const
Get string value.
#define VELOCITY_STICTIONUP
#define TORQUE_STITCTIONUP
#define VELOCITY_MAXOUTPUT
#define VELOCITY_THRESHOLD
#define VELOCITY_STICTIONDW
#define CURRENT_MAXOUTPUT
#define TORQUE_STICTIONDW
#define POSITION_STICTIONDW
#define TORQUE_VISCOUSNEG
#define POSITION_STICTIONUP
#define POSITION_MAXOUTPUT
#define TORQUE_COULOMBNEG
#define TORQUE_COULOMBPOS
#define TORQUE_VISCOUSPOS