175 lines
4.8 KiB
C++
175 lines
4.8 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 <memory>
|
|
|
|
#include "gazebo/transport/Node.hh"
|
|
|
|
#include "gazebo/common/Image.hh"
|
|
|
|
#include "gazebo/gui/viewers/ViewFactory.hh"
|
|
#include "gazebo/gui/viewers/ImagesViewPrivate.hh"
|
|
#include "gazebo/gui/viewers/ImagesView.hh"
|
|
|
|
using namespace gazebo;
|
|
using namespace gui;
|
|
|
|
GZ_REGISTER_STATIC_VIEWER("gazebo.msgs.ImagesStamped", ImagesView)
|
|
|
|
/////////////////////////////////////////////////
|
|
ImagesView::ImagesView(QWidget *_parent)
|
|
: TopicView(_parent, "gazebo.msgs.ImagesStamped", "images", 60),
|
|
dataPtr(new ImagesViewPrivate())
|
|
{
|
|
this->setWindowTitle(tr("Gazebo: Images View"));
|
|
|
|
// Create the layout and frame for images
|
|
std::unique_ptr<QGridLayout> frameLayout(new QGridLayout);
|
|
frameLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
|
|
|
this->frame->setObjectName("blackBorderFrame");
|
|
this->frame->setLayout(frameLayout.release());
|
|
this->frame->setMinimumHeight(240);
|
|
this->frame->setMinimumWidth(320);
|
|
|
|
this->dataPtr->clearImages = false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
ImagesView::~ImagesView()
|
|
{
|
|
this->sub.reset();
|
|
|
|
delete this->dataPtr;
|
|
this->dataPtr = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void ImagesView::UpdateImpl()
|
|
{
|
|
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
|
|
|
|
// Clear out the images if the flag is set.
|
|
if (this->dataPtr->clearImages)
|
|
{
|
|
// Clear previous layout
|
|
auto oldLayout = this->frame->layout();
|
|
if (oldLayout)
|
|
{
|
|
while (QLayoutItem* item = oldLayout->takeAt(0))
|
|
item->widget()->deleteLater();
|
|
|
|
oldLayout->invalidate();
|
|
}
|
|
|
|
// Make sure to adjust the size of the widget
|
|
this->frame->adjustSize();
|
|
this->adjustSize();
|
|
|
|
// Reset frame
|
|
this->dataPtr->clearImages = false;
|
|
return;
|
|
}
|
|
|
|
// Create new images when necessary
|
|
std::vector<std::pair<int, int> >::iterator iter;
|
|
for (iter = this->dataPtr->addImage.begin();
|
|
iter != this->dataPtr->addImage.end(); ++iter)
|
|
{
|
|
this->AddImage((*iter).first, (*iter).second);
|
|
}
|
|
this->dataPtr->addImage.clear();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void ImagesView::SetTopic(const std::string &_topicName)
|
|
{
|
|
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
|
|
|
|
// Tell the widget to clear the images
|
|
this->dataPtr->clearImages = true;
|
|
|
|
TopicView::SetTopic(_topicName);
|
|
|
|
// Subscribe to the new topic.
|
|
if (this->node)
|
|
this->sub = this->node->Subscribe(_topicName, &ImagesView::OnImages, this);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void ImagesView::AddImage(int _width, int _height)
|
|
{
|
|
std::unique_ptr<ImageFrame> imageFrame(new ImageFrame(NULL));
|
|
imageFrame->setBaseSize(_width, _height);
|
|
imageFrame->setMinimumSize(320, 240);
|
|
imageFrame->show();
|
|
|
|
// Add the lable to the correct row and column
|
|
auto frameLayout = qobject_cast<QGridLayout *>(this->frame->layout());
|
|
if (!frameLayout)
|
|
return;
|
|
|
|
frameLayout->addWidget(imageFrame.release(),
|
|
(frameLayout->count()) / 2,
|
|
(frameLayout->count()) % 2);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void ImagesView::OnImages(ConstImagesStampedPtr &_msg)
|
|
{
|
|
// Only use a try lock so that we don't block the node thread.
|
|
std::unique_lock<std::mutex> lock(this->dataPtr->mutex, std::try_to_lock);
|
|
if (!lock.owns_lock())
|
|
return;
|
|
|
|
if (this->dataPtr->clearImages)
|
|
return;
|
|
|
|
int dataSize = 0;
|
|
this->dataPtr->addImage.clear();
|
|
|
|
for (int i = 0; i < _msg->image_size(); ++i)
|
|
{
|
|
dataSize += _msg->image(i).data().size();
|
|
|
|
if (i >= this->frame->layout()->count())
|
|
{
|
|
this->dataPtr->addImage.push_back(std::make_pair(_msg->image(i).width(),
|
|
_msg->image(i).height()));
|
|
continue;
|
|
}
|
|
|
|
auto frameLayout = qobject_cast<QGridLayout *>(this->frame->layout());
|
|
if (!frameLayout)
|
|
continue;
|
|
|
|
auto imageFrame = qobject_cast<ImageFrame *>(
|
|
frameLayout->itemAtPosition(i / 2, i % 2)->widget());
|
|
|
|
if (imageFrame)
|
|
imageFrame->OnImage(_msg->image(i));
|
|
}
|
|
|
|
// Update the Hz and Bandwidth info
|
|
this->OnMsg(msgs::Convert(_msg->time()), dataSize);
|
|
}
|