22 #include "ui_cspacepanel.h" 24 using namespace se2ez;
31 , state_(
std::make_shared<
State>(robot))
32 , tempState_(
std::make_shared<
State>(robot))
33 , image_(xSize_, ySize_, QImage::Format_RGB32)
34 , wheel_(wheelSize_, wheelSize_, QImage::Format_RGB32)
35 , constraints_(constraints)
39 ui_->jointA_->clear();
40 ui_->jointB_->clear();
42 for (
const auto &name :
robot_->getFrameNames())
44 const auto &joint =
robot_->getFrame(name)->getJoint();
45 if (joint.joints.size() - 1 == 1)
47 ui_->jointA_->addItem(QString(name.
c_str()));
48 ui_->jointB_->addItem(QString(name.
c_str()));
52 for (
unsigned int i = 0; i < joint.joints.size() - 1; ++i)
54 const auto &name = joint.joints[i].getName();
55 ui_->jointA_->addItem(QString(name.
c_str()));
56 ui_->jointB_->addItem(QString(name.
c_str()));
61 if (
robot_->getNumJoints() > 1)
62 ui_->jointA_->setCurrentIndex(1);
64 ui_->constraints_->addItem(
"<none>");
65 for (
const auto &constraint : constraints)
66 ui_->constraints_->addItem(QString(constraint.first.c_str()));
71 connect(
ui_->jointA_, SIGNAL(currentTextChanged(
const QString &)),
this, SLOT(
updateGrid()));
72 connect(
ui_->jointB_, SIGNAL(currentTextChanged(
const QString &)),
this, SLOT(
updateGrid()));
73 connect(
ui_->states_, SIGNAL(currentTextChanged(
const QString &)),
this, SLOT(
updatePanel()));
74 connect(
ui_->constraints_, SIGNAL(currentTextChanged(
const QString &)),
this, SLOT(
updateCallback()));
75 connect(
ui_->constraintMax_, SIGNAL(valueChanged(
double)),
this, SLOT(
updateCallback()));
76 connect(
ui_->constraintPow_, SIGNAL(valueChanged(
int)),
this, SLOT(
updateCallback()));
79 connect(
ui_->doProject_, SIGNAL(clicked()),
this, SLOT(
projectState()));
87 connect(
ui_->save_, SIGNAL(clicked()),
this, SLOT(
saveImage()));
92 connect(
ui_->planpanels_, SIGNAL(currentTextChanged(
const QString &)),
this, SLOT(
updatePlanPanel()));
111 if (
ui_->sd_->isChecked() &&
ui_->colors_->isChecked())
113 else if (
ui_->sd_->isChecked())
115 else if (
ui_->colors_->isChecked())
132 QFileDialog::getSaveFileName(
this, tr(
"Save Image"),
"./cspace.png", tr(
"Image (*.png)"));
134 if (fileName.isNull())
138 unsigned int ja =
ui_->jointA_->currentIndex();
139 unsigned int jb =
ui_->jointB_->currentIndex();
140 SE2EZ_INFORM(
"Saving grid with indices %1% and %2%...", ja, jb);
142 unsigned int xSize =
ui_->xSave->value();
143 unsigned int ySize =
ui_->ySave->value();
145 QImage toSave(xSize, ySize, QImage::Format_RGB32);
146 auto temp = std::make_shared<CSpaceGrid>(
robot_, ja, jb, xSize, ySize,
getMode());
150 auto cs = temp->getImage();
152 for (
unsigned int i = 0; i < xSize; ++i)
154 auto *line = (QRgb *)toSave.scanLine(i);
155 for (
unsigned int j = 0; j < ySize; ++j)
157 auto px = cs->getPixel(xSize - i - 1, j);
158 QColor(px.red, px.green, px.blue);
159 line[j] = QColor(px.red, px.green, px.blue).rgb();
164 paint.begin(&toSave);
170 toSave.save(fileName,
"PNG");
171 SE2EZ_INFORM(
"Done saving image to %1%", fileName.toStdString());
183 grid_->waitToComplete();
192 QObject::disconnect(
jpc_);
196 QObject::disconnect(
ppc_);
207 if (
robot_->getNumJoints() > 0)
208 ui_->jointB_->setCurrentIndex(0);
210 if (
robot_->getNumJoints() > 1)
211 ui_->jointA_->setCurrentIndex(1);
224 QObject::disconnect(
ppc_);
225 QObject::disconnect(
pdc_);
229 if (
ui_->planpanels_->currentIndex() != 0)
234 auto entry =
panels->find(name);
255 ui_->slider_->blockSignals(
true);
256 ui_->slider_->setMaximum(
path_.size() - 1);
257 ui_->slider_->setEnabled(
true);
258 ui_->slider_->setValue(0);
259 ui_->slider_->blockSignals(
false);
279 if (
path_.size() &&
ui_->animate_->isChecked())
281 ui_->slider_->setValue((
ui_->slider_->value() + 1) %
ui_->slider_->maximum());
282 QTimer::singleShot(1. /
ui_->fps_->value() * 1000,
this, SLOT(
updateAnimate()));
307 QObject::disconnect(
jpc_);
310 if (
ui_->states_->currentIndex() != 0)
315 auto entry =
panels->find(name);
337 Eigen::VectorXd b =
state_->data;
345 unsigned int ja =
ui_->jointA_->currentIndex();
346 unsigned int jb =
ui_->jointB_->currentIndex();
347 a[ja] = b[ja] = a[jb] = b[jb] = 0;
367 unsigned int ja =
ui_->jointA_->currentIndex();
368 unsigned int jb =
ui_->jointB_->currentIndex();
369 SE2EZ_INFORM(
"Updating grid with indices %1% and %2%", ja, jb);
374 image_ = QImage(xCurSize_, yCurSize_, QImage::Format_RGB32);
386 auto *line = (QRgb *)
wheel_.scanLine(i);
390 double x = i - wheelSize_ / 2.;
391 double y = (wheelSize_ - j) - wheelSize_ / 2.;
396 line[j] = QColor(255. * r, 255. * g, 255. * b).rgb();
399 line[j] = QColor(255, 255, 255).rgb();
412 unsigned int iter = 0;
418 unsigned int ja =
ui_->jointA_->currentIndex();
419 unsigned int jb =
ui_->jointB_->currentIndex();
422 while ((norm = f.norm()) >
constraint_->getTolerance() && iter++ < 50)
425 Eigen::VectorXd temp = j.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(f);
443 grid_->waitToComplete();
445 if (
ui_->constraints_->currentIndex() != 0)
449 unsigned int exp =
ui_->constraintPow_->value();
450 double max =
ui_->constraintMax_->value();
451 bool jac =
ui_->jacobian_->isChecked();
452 bool drawC =
ui_->constraintCollisions_->isChecked();
453 unsigned int ja =
ui_->jointA_->currentIndex();
454 unsigned int jb =
ui_->jointB_->currentIndex();
456 callback_ = [constraint, exp, max, jac, drawC, ja, jb](ompl::PPM::Color &pixel,
457 const StatePtr &state,
bool collision) {
462 Eigen::VectorXd f(constraint->getCoDimension());
463 constraint->function(state->data, f);
477 const double max = 2.;
478 Eigen::MatrixXd j(constraint->getCoDimension(), constraint->getAmbientDimension());
479 constraint->jacobian(state->data, j);
493 if (collision and drawC)
505 pixel = ompl::PPM::Color{(
unsigned char)r, (
unsigned char)g, (
unsigned char)b};
523 if (!
ui_->display_->isChecked())
529 painter.resetTransform();
531 if (
ui_->fullscreen_->isChecked() && not
ui_->hires_->isChecked())
532 painter.scale(3., 3.);
538 painter.drawImage(p,
image_);
540 QPen pen(QColor(255, 0, 0));
555 bool edges =
ui_->edges_->isChecked();
556 bool states =
ui_->graph_->isChecked();
558 if (
pp_ &&
pd_ && (edges || states))
560 unsigned int xo = ((offset) ?
xOffset_ : 0);
561 unsigned int yo = ((offset) ?
yOffset_ : 0);
563 for (
unsigned int i = 0; i <
pd_->numVertices(); ++i)
565 const auto &vert =
pd_->getVertex(i);
568 QColor color(0, 255, 164);
569 if (vert.getTag() == 2)
570 color = QColor(0, 164, 255);
577 auto c = grid->getCoords(state);
578 unsigned int x = xo + c.y -
xPoint_ / 2.;
579 unsigned int y = yo + (grid->getHeight() - c.x) -
yPoint_ / 2.;
587 unsigned int m =
pd_->getEdges(i, edge);
589 for (
unsigned int j = 0; j < m; ++j)
594 auto lines = grid->getLines(state, next);
596 for (
const auto &line : lines)
598 unsigned int cx = xo + line.a.y;
599 unsigned int cy = yo + (grid->getHeight() - line.a.x);
601 unsigned int dx = xo + line.b.y;
602 unsigned int dy = yo + (grid->getHeight() - line.b.x);
604 painter.drawLine(cx, cy, dx, dy);
614 bool edges =
ui_->plan_->isChecked();
615 bool states =
ui_->waypoints_->isChecked();
616 if (
pp_ && (edges || states))
618 QColor color(255, 164, 0);
624 unsigned int xo = ((offset) ?
xOffset_ : 0);
625 unsigned int yo = ((offset) ?
yOffset_ : 0);
627 for (
unsigned int i = 0; i <
path_.size(); ++i)
629 const auto &state =
path_[i];
633 auto c = grid->getCoords(state);
634 unsigned int x = xo + c.y -
xPoint_ / 2.;
635 unsigned int y = yo + (grid->getHeight() - c.x) -
yPoint_ / 2.;
642 if (i <
path_.size() - 1)
644 const auto &next =
path_[i + 1];
645 auto lines = grid->getLines(state, next);
647 for (
const auto &line : lines)
649 unsigned int cx = xo + line.a.y;
650 unsigned int cy = yo + (grid->getHeight() - line.a.x);
652 unsigned int dx = xo + line.b.y;
653 unsigned int dy = yo + (grid->getHeight() - line.b.x);
655 painter.drawLine(cx, cy, dx, dy);
665 if (
jp_ &&
ui_->state_->isChecked())
667 QPen pen(QColor(255, 0, 0));
670 unsigned int xo = ((offset) ?
xOffset_ : 0);
671 unsigned int yo = ((offset) ?
yOffset_ : 0);
673 auto c = grid->getCoords(
state_);
674 unsigned int x = xo + c.y -
xPoint_ / 2.;
675 unsigned int y = yo + (grid->getHeight() - c.x) -
yPoint_ / 2.;
687 painter.drawImage(p,
wheel_);
692 double xj = j(0,
ui_->jointA_->currentIndex());
693 double yj = j(0,
ui_->jointB_->currentIndex());
700 QString s(
log::format(
"||F(q)||: %1$0.5f", d).c_str());
704 QPen pen(QColor(0, 0, 0, 100));
708 painter.drawLine(xw + ws, yw + ws,
709 xw + ws - yn, yw + ws + xn);
713 if (
ui_->project_->isChecked())
718 unsigned int xp = xo + d.y -
xPoint_ / 2.;
719 unsigned int yp = yo + (grid->getHeight() - d.x) -
yPoint_ / 2.;
721 painter.drawLine(x, y, xp, yp);
734 if (
jp_ &&
ui_->state_->isChecked())
736 unsigned int i = 0, j = 0;
740 if (
ui_->fullscreen_->isChecked() && not
ui_->hires_->isChecked())
747 if (
ui_->fullscreen_->isChecked() && not
ui_->hires_->isChecked())
753 unsigned int jai =
ui_->jointA_->currentIndex();
754 unsigned int jbi =
ui_->jointB_->currentIndex();
758 state_->data[jai] = jab.x;
759 state_->data[jbi] = jab.y;
777 if (not
grid_->isComputing())
784 auto cs =
grid_->getImage();
785 for (
unsigned int i = 0; i <
xCurSize_; ++i)
787 auto *line = (QRgb *)
image_.scanLine(i);
788 for (
unsigned int j = 0; j <
yCurSize_; ++j)
790 auto px = cs->getPixel(xCurSize_ - i - 1, j);
791 line[j] = QColor(px.red, px.green, px.blue).rgb();
799 for (
const auto &panel : *
panels)
807 if (jpanel->getSignature().compare(
robot_->getSignature()) == 0)
831 ui_->states_->clear();
832 ui_->planpanels_->clear();
835 ui_->states_->addItem(
"<none>");
837 ui_->states_->addItem(QString(
name.c_str()));
840 ui_->states_->setCurrentIndex(1);
843 ui_->planpanels_->addItem(
"<none>");
845 ui_->planpanels_->addItem(QString(
name.c_str()));
848 ui_->planpanels_->setCurrentIndex(1);
void draw(QPainter &painter, RenderArea *canvas) override
void plasma(double s, double &r, double &g, double &b)
Maps a scalar s in [0, 1] to the Plasma colormap.
A shared pointer wrapper for se2ez::State.
std::set< std::string > pnames_
CSpacePanel(RobotPtr robot, std::string name, std::map< std::string, ompl::base::ConstraintPtr > constraints={}, QWidget *parent=0)
A representation of a state of a Robot.
const unsigned int xSize_
void setState(const StatePtr &state)
const unsigned int HiRes_
const unsigned int ySize_
ompl::base::ConstraintPtr constraint_
double clamp(double v, double a, double b)
Clamp a value v between a range [a, b].
const unsigned int wheelSize_
Mode
Drawing mode for the grid.
QMetaObject::Connection jpc_
void drawState(QPainter &painter, CSpaceGridPtr &grid, bool offset, bool interface=true)
const unsigned int xPoint_
#define SE2EZ_INFORM(fmt,...)
const unsigned int yOffset_
const unsigned int xBorder_
std::vector< StatePtr > path_
std::set< std::string > panelnames_
void updateImage(bool force=false)
ompl::base::PlannerDataPtr getPlannerData()
A shared pointer wrapper for se2ez::CSpaceGrid.
const unsigned int xOffset_
void drawGraph(QPainter &painter, CSpaceGridPtr &grid, bool offset)
void getState(StatePtr state)
ompl::base::PlannerDataPtr pd_
const unsigned int yText_
const unsigned int yPoint_
MainWindow::PanelMapPtr panels
const unsigned int yBorder_
CSpaceGrid::Mode getMode() const
Use viridis color palette for signed distance.
Draw collisions as black pixels.
A shared pointer wrapper for se2ez::Robot.
std::string format(const std::string &fmt, Args &&... args)
QMetaObject::Connection pdc_
void hsv2rgb(double h, double s, double v, double &r, double &g, double &b)
Convert a RGB color to HSV.
std::set< std::string > jnames_
Signed distance, but penetrations are colored by geometry.
The canvas widget. It contains all the drawing functions as well as all the general settings for draw...
Color obstacles by geometry color.
const std::vector< StatePtr > & getPath() const
bool click(QMouseEvent *event, double x, double y, int sx, int sy) override
double remap(double a1, double a2, double av, double b1, double b2)
Remap a value av in the interval a1, a2 to the interval b1, b2.
QMetaObject::Connection ppc_
void drawPlan(QPainter &painter, CSpaceGridPtr &grid, bool offset, bool bold)
CSpaceGrid::GridCallback callback_
std::map< std::string, ompl::base::ConstraintPtr > constraints_
void toGrayscale(double &r, double &g, double &b)
Maps an RGB color to a greyscale color based on luminosity.