pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/gui/JointControlWidget.cc

753 lines
24 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include "gazebo/transport/Node.hh"
#include "gazebo/transport/TransportIface.hh"
#include "gazebo/gui/GuiIface.hh"
#include "gazebo/gui/JointControlWidget.hh"
#include "gazebo/gui/JointControlWidgetPrivate.hh"
using namespace gazebo;
using namespace gui;
/////////////////////////////////////////////////
JointForceControl::JointForceControl(const std::string &_name,
QGridLayout *_layout, QWidget *_parent, int _index)
: QWidget(_parent),
dataPtr(new JointForceControlPrivate())
{
this->dataPtr->name = _name;
this->dataPtr->forceSpin = new QDoubleSpinBox;
this->dataPtr->forceSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->forceSpin->setSingleStep(0.001);
this->dataPtr->forceSpin->setDecimals(3);
this->dataPtr->forceSpin->setValue(0.000);
_layout->addWidget(this->dataPtr->forceSpin, _index, 2);
connect(this->dataPtr->forceSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnChanged(double)));
}
/////////////////////////////////////////////////
JointForceControl::~JointForceControl()
{
this->hide();
}
/////////////////////////////////////////////////
void JointForceControl::Reset()
{
this->dataPtr->forceSpin->setValue(0.0);
}
/////////////////////////////////////////////////
void JointForceControl::OnChanged(double _value)
{
emit changed(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
JointPIDPosControl::JointPIDPosControl(const std::string &_name,
QGridLayout *_layout, QWidget *_parent, int _index)
: QWidget(_parent),
dataPtr(new JointPIDPosControlPrivate())
{
this->dataPtr->name = _name;
this->dataPtr->posSpin = new QDoubleSpinBox;
this->dataPtr->posSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->posSpin->setSingleStep(0.001);
this->dataPtr->posSpin->setDecimals(3);
this->dataPtr->posSpin->setValue(0.000);
this->dataPtr->pGainSpin = new QDoubleSpinBox;
this->dataPtr->pGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->pGainSpin->setSingleStep(0.01);
this->dataPtr->pGainSpin->setDecimals(3);
this->dataPtr->pGainSpin->setValue(1.000);
this->dataPtr->iGainSpin = new QDoubleSpinBox;
this->dataPtr->iGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->iGainSpin->setSingleStep(0.01);
this->dataPtr->iGainSpin->setDecimals(3);
this->dataPtr->iGainSpin->setValue(0.100);
this->dataPtr->dGainSpin = new QDoubleSpinBox;
this->dataPtr->dGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->dGainSpin->setSingleStep(0.01);
this->dataPtr->dGainSpin->setDecimals(3);
this->dataPtr->dGainSpin->setValue(0.010);
_layout->addWidget(this->dataPtr->posSpin, _index, 2);
_layout->addWidget(this->dataPtr->pGainSpin, _index, 3);
_layout->addWidget(this->dataPtr->iGainSpin, _index, 4);
_layout->addWidget(this->dataPtr->dGainSpin, _index, 5);
connect(this->dataPtr->posSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnChanged(double)));
connect(this->dataPtr->pGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnPChanged(double)));
connect(this->dataPtr->iGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnIChanged(double)));
connect(this->dataPtr->dGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnDChanged(double)));
this->dataPtr->radians = true;
}
/////////////////////////////////////////////////
JointPIDPosControl::~JointPIDPosControl()
{
}
/////////////////////////////////////////////////
void JointPIDPosControl::Reset()
{
this->dataPtr->posSpin->setValue(0.0);
this->dataPtr->pGainSpin->setValue(1.000);
this->dataPtr->iGainSpin->setValue(0.100);
this->dataPtr->dGainSpin->setValue(0.010);
}
/////////////////////////////////////////////////
void JointPIDPosControl::SetToDegrees()
{
if (this->dataPtr->radians)
{
this->dataPtr->radians = false;
this->dataPtr->posSpin->setValue(GZ_RTOD(this->dataPtr->posSpin->value()));
}
}
/////////////////////////////////////////////////
void JointPIDPosControl::SetToRadians()
{
if (!this->dataPtr->radians)
{
this->dataPtr->radians = true;
this->dataPtr->posSpin->setValue(GZ_DTOR(this->dataPtr->posSpin->value()));
}
}
/////////////////////////////////////////////////
void JointPIDPosControl::OnChanged(double _value)
{
if (this->dataPtr->radians)
emit changed(_value, this->dataPtr->name);
else
emit changed(GZ_DTOR(_value), this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDPosControl::OnPChanged(double _value)
{
emit pChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDPosControl::OnIChanged(double _value)
{
emit iChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDPosControl::OnDChanged(double _value)
{
emit dChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
JointPIDVelControl::JointPIDVelControl(const std::string &_name,
QGridLayout *_layout, QWidget *_parent, int _index)
: QWidget(_parent),
dataPtr(new JointPIDVelControlPrivate())
{
this->dataPtr->name = _name;
this->dataPtr->posSpin = new QDoubleSpinBox;
this->dataPtr->posSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->posSpin->setSingleStep(0.001);
this->dataPtr->posSpin->setDecimals(3);
this->dataPtr->posSpin->setValue(0.000);
this->dataPtr->pGainSpin = new QDoubleSpinBox;
this->dataPtr->pGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->pGainSpin->setSingleStep(0.01);
this->dataPtr->pGainSpin->setDecimals(3);
this->dataPtr->pGainSpin->setValue(1.000);
this->dataPtr->iGainSpin = new QDoubleSpinBox;
this->dataPtr->iGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->iGainSpin->setSingleStep(0.01);
this->dataPtr->iGainSpin->setDecimals(3);
this->dataPtr->iGainSpin->setValue(0.100);
this->dataPtr->dGainSpin = new QDoubleSpinBox;
this->dataPtr->dGainSpin->setRange(-IGN_DBL_MAX, IGN_DBL_MAX);
this->dataPtr->dGainSpin->setSingleStep(0.01);
this->dataPtr->dGainSpin->setDecimals(3);
this->dataPtr->dGainSpin->setValue(0.010);
_layout->addWidget(this->dataPtr->posSpin, _index, 2);
_layout->addWidget(this->dataPtr->pGainSpin, _index, 3);
_layout->addWidget(this->dataPtr->iGainSpin, _index, 4);
_layout->addWidget(this->dataPtr->dGainSpin, _index, 5);
connect(this->dataPtr->posSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnChanged(double)));
connect(this->dataPtr->pGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnPChanged(double)));
connect(this->dataPtr->iGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnIChanged(double)));
connect(this->dataPtr->dGainSpin, SIGNAL(valueChanged(double)),
this, SLOT(OnDChanged(double)));
}
/////////////////////////////////////////////////
JointPIDVelControl::~JointPIDVelControl()
{
}
/////////////////////////////////////////////////
void JointPIDVelControl::Reset()
{
this->dataPtr->posSpin->setValue(0.0);
this->dataPtr->pGainSpin->setValue(1.000);
this->dataPtr->iGainSpin->setValue(0.100);
this->dataPtr->dGainSpin->setValue(0.010);
}
/////////////////////////////////////////////////
void JointPIDVelControl::OnChanged(double _value)
{
emit changed(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDVelControl::OnPChanged(double _value)
{
emit pChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDVelControl::OnIChanged(double _value)
{
emit iChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointPIDVelControl::OnDChanged(double _value)
{
emit dChanged(_value, this->dataPtr->name);
}
/////////////////////////////////////////////////
void JointControlWidget::SetModelName(const std::string &_modelName)
{
if (this->dataPtr->jointPub)
{
this->dataPtr->jointPub->Fini();
this->dataPtr->jointPub.reset();
}
msgs::Model modelMsg;
this->dataPtr->modelLabel->setText(
QString::fromStdString(std::string("Model: ")));
// Only request info if the model has a name.
if (!_modelName.empty())
{
this->dataPtr->jointPub = this->dataPtr->node->Advertise<msgs::JointCmd>(
std::string("~/") + _modelName + "/joint_cmd");
boost::shared_ptr<msgs::Response> response = transport::request(
gui::get_world(), "entity_info", _modelName);
if (response->response() != "error" &&
response->type() == modelMsg.GetTypeName())
{
modelMsg.ParseFromString(response->serialized_data());
}
}
this->dataPtr->modelLabel->setText(QString::fromStdString(
std::string("Model: ") + modelMsg.name()));
this->LayoutForceTab(modelMsg);
this->LayoutPositionTab(modelMsg);
this->LayoutVelocityTab(modelMsg);
}
/////////////////////////////////////////////////
JointControlWidget::JointControlWidget(QWidget *_parent)
: QWidget(_parent),
dataPtr(new JointControlWidgetPrivate())
{
this->setObjectName("jointControl");
this->setWindowTitle("Joint Control");
this->dataPtr->node = transport::NodePtr(new transport::Node());
this->dataPtr->node->TryInit(common::Time::Maximum());
this->dataPtr->tabWidget = new QTabWidget;
this->dataPtr->tabWidget->setObjectName("embeddedTab");
// Create the Force control scroll area
this->dataPtr->forceGridLayout = new QGridLayout;
this->AddScrollTab(
this->dataPtr->tabWidget, this->dataPtr->forceGridLayout, tr("Force"));
// Create a PID Pos scroll area
this->dataPtr->positionGridLayout = new QGridLayout;
this->AddScrollTab(this->dataPtr->tabWidget,
this->dataPtr->positionGridLayout, tr("Position"));
// Create a PID Vel scroll area
this->dataPtr->velocityGridLayout = new QGridLayout;
this->AddScrollTab(this->dataPtr->tabWidget,
this->dataPtr->velocityGridLayout, tr("Velocity"));
// Add the the force and pid scroll areas to the tab
QVBoxLayout *mainLayout = new QVBoxLayout;
QHBoxLayout *hboxLayout = new QHBoxLayout;
this->dataPtr->modelLabel = new QLabel(tr("Model: "));
hboxLayout->addWidget(this->dataPtr->modelLabel);
hboxLayout->addItem(new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum));
QPushButton *resetButton = new QPushButton(tr("Reset"));
connect(resetButton, SIGNAL(clicked()), this, SLOT(OnReset()));
hboxLayout->addWidget(resetButton);
mainLayout->addLayout(hboxLayout);
mainLayout->addWidget(this->dataPtr->tabWidget);
mainLayout->setContentsMargins(4, 4, 4, 4);
this->setLayout(mainLayout);
}
/////////////////////////////////////////////////
JointControlWidget::~JointControlWidget()
{
}
/////////////////////////////////////////////////
void JointControlWidget::OnReset()
{
for (std::map<std::string, JointForceControl*>::iterator iter =
this->dataPtr->sliders.begin();
iter != this->dataPtr->sliders.end(); ++iter)
{
msgs::JointCmd msg;
msg.set_name(iter->first);
msg.set_reset(true);
this->dataPtr->jointPub->Publish(msg);
iter->second->Reset();
}
for (std::map<std::string, JointPIDPosControl*>::iterator iter =
this->dataPtr->pidPosSliders.begin();
iter != this->dataPtr->pidPosSliders.end(); ++iter)
{
iter->second->Reset();
}
for (std::map<std::string, JointPIDVelControl*>::iterator iter =
this->dataPtr->pidVelSliders.begin();
iter != this->dataPtr->pidVelSliders.end(); ++iter)
{
iter->second->Reset();
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnForceChanged(double _value, const std::string &_name)
{
std::map<std::string, JointForceControl*>::iterator iter;
iter = this->dataPtr->sliders.find(_name);
if (iter != this->dataPtr->sliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.set_force(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnPIDPosChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDPosControl*>::iterator iter;
iter = this->dataPtr->pidPosSliders.find(_name);
if (iter != this->dataPtr->pidPosSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_position()->set_target(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnPPosGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDPosControl*>::iterator iter;
iter = this->dataPtr->pidPosSliders.find(_name);
if (iter != this->dataPtr->pidPosSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_position()->set_p_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnDPosGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDPosControl*>::iterator iter;
iter = this->dataPtr->pidPosSliders.find(_name);
if (iter != this->dataPtr->pidPosSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_position()->set_d_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnIPosGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDPosControl*>::iterator iter;
iter = this->dataPtr->pidPosSliders.find(_name);
if (iter != this->dataPtr->pidPosSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_position()->set_i_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnPIDPosUnitsChanged(int _index)
{
std::map<std::string, JointPIDPosControl*>::iterator iter;
for (iter = this->dataPtr->pidPosSliders.begin();
iter != this->dataPtr->pidPosSliders.end(); ++iter)
{
if (_index == 0)
iter->second->SetToRadians();
else
iter->second->SetToDegrees();
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnPIDVelChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDVelControl*>::iterator iter;
iter = this->dataPtr->pidVelSliders.find(_name);
if (iter != this->dataPtr->pidVelSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_velocity()->set_target(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnPVelGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDVelControl*>::iterator iter;
iter = this->dataPtr->pidVelSliders.find(_name);
if (iter != this->dataPtr->pidVelSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_velocity()->set_p_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnDVelGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDVelControl*>::iterator iter;
iter = this->dataPtr->pidVelSliders.find(_name);
if (iter != this->dataPtr->pidVelSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_velocity()->set_d_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::OnIVelGainChanged(double _value,
const std::string &_name)
{
std::map<std::string, JointPIDVelControl*>::iterator iter;
iter = this->dataPtr->pidVelSliders.find(_name);
if (iter != this->dataPtr->pidVelSliders.end())
{
msgs::JointCmd msg;
msg.set_name(_name);
msg.mutable_velocity()->set_i_gain(_value);
this->dataPtr->jointPub->Publish(msg);
}
}
/////////////////////////////////////////////////
void JointControlWidget::AddScrollTab(QTabWidget *_tabPane,
QGridLayout *_tabLayout, const QString &_name)
{
_tabLayout->setSizeConstraint(QLayout::SetMinimumSize);
QScrollArea *scrollArea = new QScrollArea(this);
scrollArea->setLineWidth(0);
scrollArea->setFrameShape(QFrame::NoFrame);
scrollArea->setFrameShadow(QFrame::Plain);
scrollArea->setSizePolicy(QSizePolicy::Minimum,
QSizePolicy::Minimum);
// Make the scroll area automatically resize to the containing widget.
scrollArea->setWidgetResizable(true);
QFrame *frame = new QFrame(scrollArea);
frame->setObjectName("pidControl");
frame->setLineWidth(0);
frame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
frame->setLayout(_tabLayout);
scrollArea->setWidget(frame);
_tabPane->addTab(scrollArea, _name);
}
/////////////////////////////////////////////////
void JointControlWidget::LayoutForceTab(msgs::Model &_modelMsg)
{
// Remove the old widgets;
QLayoutItem *wItem;
while ((wItem = this->dataPtr->forceGridLayout->takeAt(0)) != NULL)
{
if (wItem->widget())
delete wItem->widget();
delete wItem;
}
this->dataPtr->sliders.clear();
// Don't add any widget if there are no joints
if (_modelMsg.joint_size() == 0)
return;
this->dataPtr->forceGridLayout->addItem(new QSpacerItem(
10, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0, 2);
this->dataPtr->forceGridLayout->addWidget(new QLabel(
"Newton-meter", this), 0, 2);
int i = 0;
for (; i < _modelMsg.joint_size(); ++i)
{
std::string jointName = _modelMsg.joint(i).name();
// Get the joint name minus the model name
int modelNameIndex = jointName.find("::") + 2;
std::string shortName = jointName.substr(modelNameIndex,
jointName.size() - modelNameIndex);
this->dataPtr->forceGridLayout->addWidget(new QLabel(
tr(shortName.c_str())), i+1, 0);
this->dataPtr->forceGridLayout->addItem(new QSpacerItem(
10, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), i+1, 1);
JointForceControl *slider = new JointForceControl(jointName,
this->dataPtr->forceGridLayout, this, i+1);
this->dataPtr->sliders[jointName] = slider;
connect(slider, SIGNAL(changed(double, const std::string &)),
this, SLOT(OnForceChanged(double, const std::string &)));
}
// Add a space at the bottom of the grid layout to consume extra space.
this->dataPtr->forceGridLayout->addItem(new QSpacerItem(
10, 20, QSizePolicy::Expanding, QSizePolicy::Expanding), i+1, 0);
this->dataPtr->forceGridLayout->setRowStretch(i+1, 2);
}
/////////////////////////////////////////////////
void JointControlWidget::LayoutPositionTab(msgs::Model &_modelMsg)
{
// Remove the old widgets;
QLayoutItem *wItem;
while ((wItem = this->dataPtr->positionGridLayout->takeAt(0)) != NULL)
{
if (wItem->widget())
delete wItem->widget();
delete wItem;
}
this->dataPtr->pidPosSliders.clear();
// Don't add any widget if there are no joints
if (_modelMsg.joint_size() == 0)
return;
this->dataPtr->positionGridLayout->addItem(new QSpacerItem(10, 20,
QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0, 2);
QComboBox *unitsCombo = new QComboBox;
unitsCombo->addItem("Radians");
unitsCombo->addItem("Degrees");
connect(unitsCombo, SIGNAL(currentIndexChanged(int)),
this, SLOT(OnPIDPosUnitsChanged(int)));
this->dataPtr->positionGridLayout->addWidget(unitsCombo, 0, 2);
this->dataPtr->positionGridLayout->addWidget(new QLabel(
"P Gain", this), 0, 3);
this->dataPtr->positionGridLayout->addWidget(new QLabel(
"I Gain", this), 0, 4);
this->dataPtr->positionGridLayout->addWidget(new QLabel(
"D Gain", this), 0, 5);
int i = 0;
for (; i < _modelMsg.joint_size(); ++i)
{
std::string jointName = _modelMsg.joint(i).name();
// Get the joint name minus the model name
int modelNameIndex = jointName.find("::") + 2;
std::string shortName = jointName.substr(modelNameIndex,
jointName.size() - modelNameIndex);
this->dataPtr->positionGridLayout->addWidget(
new QLabel(tr(shortName.c_str())), i+1, 0);
this->dataPtr->positionGridLayout->addItem(
new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum), i+1, 1);
JointPIDPosControl *slider = new JointPIDPosControl(jointName,
this->dataPtr->positionGridLayout, this, i+1);
this->dataPtr->pidPosSliders[jointName] = slider;
connect(slider, SIGNAL(changed(double, const std::string &)),
this, SLOT(OnPIDPosChanged(double, const std::string &)));
connect(slider, SIGNAL(pChanged(double, const std::string &)),
this, SLOT(OnPPosGainChanged(double, const std::string &)));
connect(slider, SIGNAL(iChanged(double, const std::string &)),
this, SLOT(OnIPosGainChanged(double, const std::string &)));
connect(slider, SIGNAL(dChanged(double, const std::string &)),
this, SLOT(OnDPosGainChanged(double, const std::string &)));
}
// Add a space at the bottom of the grid layout to consume extra space.
this->dataPtr->positionGridLayout->addItem(
new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Expanding), i+1, 0);
this->dataPtr->positionGridLayout->setRowStretch(i+1, 2);
}
/////////////////////////////////////////////////
void JointControlWidget::LayoutVelocityTab(msgs::Model &_modelMsg)
{
// Remove the old widgets;
QLayoutItem *wItem;
while ((wItem = this->dataPtr->velocityGridLayout->takeAt(0)) != NULL)
{
if (wItem->widget())
delete wItem->widget();
delete wItem;
}
this->dataPtr->pidVelSliders.clear();
// Don't add any widget if there are no joints
if (_modelMsg.joint_size() == 0)
return;
this->dataPtr->velocityGridLayout->addItem(
new QSpacerItem(10, 27, QSizePolicy::Expanding,
QSizePolicy::Minimum), 0, 0, 2);
// Set fixed height for the label to make the tabs stay a consistent size.
QLabel *label = new QLabel("m/s", this);
label->setFixedHeight(27);
this->dataPtr->velocityGridLayout->addWidget(label, 0, 2);
this->dataPtr->velocityGridLayout->addWidget(new QLabel(
"P Gain", this), 0, 3);
this->dataPtr->velocityGridLayout->addWidget(new QLabel(
"I Gain", this), 0, 4);
this->dataPtr->velocityGridLayout->addWidget(new QLabel(
"D Gain", this), 0, 5);
int i = 0;
for (; i < _modelMsg.joint_size(); ++i)
{
std::string jointName = _modelMsg.joint(i).name();
// Get the joint name minus the model name
int modelNameIndex = jointName.find("::") + 2;
std::string shortName = jointName.substr(modelNameIndex,
jointName.size() - modelNameIndex);
this->dataPtr->velocityGridLayout->addWidget(
new QLabel(tr(shortName.c_str())), i+1, 0);
this->dataPtr->velocityGridLayout->addItem(
new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum), i+1, 1);
JointPIDVelControl *slider = new JointPIDVelControl(
jointName, this->dataPtr->velocityGridLayout, this, i+1);
this->dataPtr->pidVelSliders[jointName] = slider;
connect(slider, SIGNAL(changed(double, const std::string &)),
this, SLOT(OnPIDVelChanged(double, const std::string &)));
connect(slider, SIGNAL(pChanged(double, const std::string &)),
this, SLOT(OnPVelGainChanged(double, const std::string &)));
connect(slider, SIGNAL(iChanged(double, const std::string &)),
this, SLOT(OnIVelGainChanged(double, const std::string &)));
connect(slider, SIGNAL(dChanged(double, const std::string &)),
this, SLOT(OnDVelGainChanged(double, const std::string &)));
}
// Add a space at the bottom of the grid layout to consume extra space.
this->dataPtr->velocityGridLayout->addItem(
new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Expanding), i+1, 0);
this->dataPtr->velocityGridLayout->setRowStretch(i+1, 2);
}