Filter a point cloud real time... PCL - point-cloud-library

I wanna display a point cloud filtered in real time, I mean not from PCD files, I've been trying to manipulate the example code from PCL Documentation, I'm new at this stuff and c++ beginner. Here's my code, it has errors, but I can't understand. :(
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
Class SimpleOpenNIViewer
{
public:
SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}
pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_filtered;
void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
{
if (!viewer.wasStopped()){
pcl::VoxelGrid<pcl::PointCloud<pcl::PointXYZ> sor;
sor.setInputCloud (cloud);
sor.setLeafSize (0.01f, 0.01f, 0.01f);
sor.filter (*cloud_filtered);
viewer.showCloud (cloud_filtered);
}
}
void run ()
{
pcl::Grabber* interface = new pcl::OpenNIGrabber();
boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f =
boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);
interface->registerCallback (f);
interface->start ();
while (!viewer.wasStopped())
{
boost::this_thread::sleep (boost::posix_time::seconds (1));
}
interface->stop ();
}
pcl::visualization::CloudViewer viewer;
};
int main ()
{
SimpleOpenNIViewer v;
v.run ();
return 0;
}

The error:
sor.setInputCloud (cloud);
sor.setLeafSize (0.01f, 0.01f, 0.01f);
sor.filter (*cloud_filtered);
viewer.showCloud (*cloud_filtered);// I guess with this the error is solved

Related

dbus-send to QDBus program example

I try to send a message via dbus-send to this small example program.
But it is not received:
dbus-send --session --type=method_call / dbustester.test.slot_foo
The return code is 0 and not message is printed to the console.
Below is the source code.
main.cpp
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtDBus/QtDBus>
#include <Example.h>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
Example *e = new Example();
e->setupDBus();
return app.exec();
}
Example.h
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtDBus/QtDBus>
class Example : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "dbustester.test")
public:
Example(QObject* parent = NULL) :
QObject(parent)
{
}
void setupDBus()
{
QDBusConnection session = QDBusConnection::sessionBus();
if (!session.isConnected())
{
qFatal("Cannot connect to the D-Bus session bus.");
return;
}
session.connect("", "/", "dbustester.test", "slot_foo", this, SLOT(slot_foo(void)));
if(!session.registerObject("/", this, QDBusConnection::ExportScriptableContents)) {
qFatal("Cannot registerObject.");
return;
}
if(!session.registerService("dbustester.test")) {
qFatal("Cannot registerObject.");
return;
}
}
public slots:
Q_SCRIPTABLE void slot_foo()
{
qDebug() << "request received";
}
};
Build:
qmake -project
echo "CONFIG += qdbus" >> *.pro
qmake
I've found the answer while writing the question, but I wrote the question anyway. Some people might find it useful.
dbus-send --session --dest=dbustester.test --type=method_call / dbustester.test.slot_foo
I forgot the --dest argument. :>

declaring global struct pointer in c++ for linked list in unix (putty)

I'm trying to create a linked list data structure for a mobile store database. I'm facing problems in declaring a global pointer for struct mobile. In the method view_all(), im not able to get the output of the entered variables.
I'm executing this code as mobile.cpp with the help of putty in unix operating system.
#include <iostream>
#include <iomanip>
using namespace std;
struct mobile
{
char make[15];
char model[10];
float price;
mobile *link;
}*start;
void add_new ()
{
struct mobile *temp, *traverse;
temp = new struct mobile;
traverse = start;
if (start==NULL)
{
temp=start;
}
else
{
while (traverse->link!=NULL)
{
traverse=traverse->link;
}
traverse->link=temp;
}
temp->make="BlackBerry";
temp->model="BB9320";
temp->price=12000;
}
void view_all ()
{
struct mobile *temp;
temp = new struct mobile;
temp=start;
cout <<"Mobile make:"<<temp->make;
cout <<"Mobile price:"<<temp->price;
}
int main ()
{
add_new ();
view_all ();
return 0;
}

connecting a signal of widget in a plasmoid

I am new to Qt and am trying to connect the cilicked signal o a push button with a function hile writing a plasmoid. I am trying to use an external function as a public with Plasma::PushButton type object so that I can use it to connect it with the clicked signal? With gtk it was as simple as on_...._clicked do this but isnt there a simple way in qt, where we can do away with the need to use slots?
#include "plasma-tutorial1.h"
#include<string.h>
#include <stdlib.h>
#include <QGraphicsLinearLayout>
#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>
#include <QTextEdit>
#include <plasma/svg.h>
#include <plasma/theme.h>
#include <plasma/widgets/lineedit.h>
#include <plasma/widgets/pushbutton.h>
#include <plasma/widgets/textedit.h>
//PlasmaTutorial1 mainf;
themainfunction(int choice,Plasma::LineEdit *m_lineEdit,
Plasma::TextEdit *m_displaytext)
{
char buffer[100];
const char *inp=(const char *)malloc(sizeof(char)*100);
QString input;
input=m_lineEdit->text();
QByteArray byteArray = input.toUtf8();
inp = byteArray.constData();
char *expression;
expression=(char *)malloc(sizeof(char)*100);
strcpy(expression,"sudo apt-");
switch(choice)
{
case 1:{
strcat(expression,"get install ");
strcat(expression,inp);
break;
};
case 2:{
strcat(expression,"get remove ");
strcat(expression,inp);
break;
};
case 3:{
strcat(expression,"cache search ");
strcat(expression,inp);
break;
};
};
/*
FILE* in;
FILE* ptr=fopen("new.txt","w");
FILE *popen();
if(!(in = popen("cal","r")))
{return;}
while(fgets(buffer, 100, in) != NULL) {
*/
m_displaytext->append("yeah!");
// fprintf(ptr,"%s",buffer);
//}
//pclose(in);
//fclose(ptr);
}
PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args),
m_svg(this),
m_icon("document")
{
m_svg.setImagePath("widgets/background");
// this will get us the standard applet background, for free!
setBackgroundHints(DefaultBackground);
resize(200, 200);
}
PlasmaTutorial1::~PlasmaTutorial1()
{
if (hasFailedToLaunch()) {
// Do some cleanup here
} else {
// Save settings
}
}
void PlasmaTutorial1::init()
{
/* // A small demonstration of the setFailedToLaunch function
if (m_icon.isNull()) {
setFailedToLaunch(true, "No world to say hello");
}*/
Counter rt;
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
layout->setOrientation(Qt::Vertical); //so widgets will be stacked up/down
m_lineEdit = new Plasma::LineEdit(this);
m_lineEdit->setText("Enter the package name here");
m_displaytext = new Plasma::TextEdit(this);
m_displaytext->setText("Terminal");
m_installButton = new Plasma::PushButton(this);
m_installButton->setText("Install");
connect(m_installButton, SIGNAL(clicked()),&rt,SLOT(themainfunction(1,m_lineEdit,m_displaytext)));
m_removeButton = new Plasma::PushButton(this);
m_removeButton->setText("Remove");
// m_removeButton->clicked()
connect(m_removeButton, SIGNAL(clicked()),&rt,SLOT(themainfunction(2,m_lineEdit,m_displaytext)));
m_searchButton = new Plasma::PushButton(this);
m_searchButton->setText("Search");
connect(m_searchButton, SIGNAL(clicked()),&rt,SLOT(themainfunction(3,m_lineEdit,m_displaytext)));
layout->addItem(m_lineEdit);
layout->addItem(m_installButton);
layout->addItem(m_removeButton);
layout->addItem(m_searchButton);
layout->addItem(m_displaytext);
m_displaytext->append("yo baby!");
}
/*
void PlasmaTutorial1::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);
// Now we draw the applet, starting with our svg
m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
// We place the icon and text
p->drawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(),(int)contentsRect.width()-14));
p->save();
p->setPen(Qt::white);
p->drawText(contentsRect,
Qt::AlignBottom | Qt::AlignHCenter,
"Hello Plasmoid!");
p->restore();
}
*/
// This is the command that links your applet to the .desktop file
K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
#include "plasma-tutorial1.moc"
say i want to connect themainfunction() upon clicked signal of install button . how do i do it? how can I derive a class in plasma?
i got where was i missing out. We cannot pass objects as arguments in slot functions. Now it is running smooth. thanx for all your replies.

Asynchronously Run Console Output and GUI in Qt

I am working on building a GUI around a console application. I would like to be able to click a button to run the console app and show the console output inside of the GUI itself. How might I accomplish this? I am working in Linux.
You could also try QProcess. It provides a Qt interface to launching external processes, reading their I/O and waiting, or not, on their completion.
For your purpose, it sounds like you want the process to run asynchronously, so code might look like :
myprocessstarter.h :
#include <QObject>
#include <QProcess>
#include <QDebug>
class MyProcessStarter : public QObject
{
Q_OBJECT
public:
MyProcessStarter() : QObject() {};
void StartProcess();
private slots:
void readStandardOutput();
private:
QProcess *myProcess;
};
main.cpp:
#include "myprocessstarter.h"
void MyProcessStarter::StartProcess()
{
QString program = "dir";
QStringList arguments;
// Add any arguments you want to be passed
myProcess = new QProcess(this);
connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
myProcess->start(program, arguments);
}
void MyProcessStarter::readStandardOutput()
{
QByteArray processOutput;
processOutput = myProcess->readAllStandardOutput();
qDebug() << "Output was " << QString(processOutput);
}
void main(int argc, char** argv)
{
MyProcessStarter s;
s.StartProcess();
}
I wanted to do something similar in one of my applications. I redirected all output from the standard stream (cout) to my console window. To periodically read out the stream contents I use a timer loop. Works fine for me.
StdRedirector.cpp
#include "StdRedirector.h"
QMutex coutMutex;
void outcallback(const char* ptr, std::streamsize count, void* bufferString)
{
string *b = (string *) bufferString;
string t;
for (int i=0; i < count; i++)
{
if (ptr[i] == '\n')
{
t = t + "\n";
} else {
t = t + ptr[i];
}
}
coutMutex.lock();
*b = *b + t;
coutMutex.unlock();
}
void ConsoleWindow::updateTimer(void)
{
coutMutex.lock();
if (bufferString.size() > 0)
{
consoleBox->insertPlainText(QString(bufferString.c_str()));
bufferString.clear();
QScrollBar *sb = consoleBox->verticalScrollBar();
sb->setValue(sb->maximum());
}
coutMutex.unlock();
}
ConsoleWindow::ConsoleWindow(QWidget *parent) : QWidget(parent)
{
consoleBox = new QTextEdit(this);
consoleBox->setReadOnly(true);
stdRedirector = new StdRedirector<>(std::cout, outcallback, &bufferString);
QVBoxLayout *vb = new QVBoxLayout();
vb->addWidget(consoleBox);
vb->setMargin(0);
vb->setSpacing(0);
setLayout(vb);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTimer()));
timer->start(100);
}
ConsoleWindow::~ConsoleWindow()
{
delete stdRedirector;
}
StdRedirector.h
#ifndef STD_REDIRECTOR
#define STD_REDIRECTOR
#include <QWidget>
#include <QTextEdit>
#include <QString>
#include <QVBoxLayout>
#include <QTimer.h>
#include <QMutex>
#include <QScrollBar>
#include <iostream>
#include <string>
using namespace std;
template<class Elem = char, class Tr = std::char_traits<Elem>>
class StdRedirector : public std::basic_streambuf<Elem, Tr>
{
typedef void (*pfncb) ( const Elem*, std::streamsize _Count, void* pUsrData );
public:
StdRedirector(std::ostream& a_Stream, pfncb a_Cb, void* a_pUsrData) :
m_Stream(a_Stream),
m_pCbFunc(a_Cb),
m_pUserData(a_pUsrData)
{
m_pBuf = m_Stream.rdbuf(this);
}
~StdRedirector()
{
m_Stream.rdbuf(m_pBuf);
}
std::streamsize xsputn(const Elem* _Ptr, std::streamsize _Count)
{
m_pCbFunc(_Ptr, _Count, m_pUserData);
return _Count;
}
typename Tr::int_type overflow(typename Tr::int_type v)
{
Elem ch = Tr::to_char_type(v);
m_pCbFunc(&ch, 1, m_pUserData);
return Tr::not_eof(v);
}
protected:
std::basic_ostream<Elem, Tr>& m_Stream;
std::streambuf* m_pBuf;
pfncb m_pCbFunc;
void* m_pUserData;
};
class ConsoleWindow : public QWidget
{
Q_OBJECT
public:
ConsoleWindow(QWidget *parent = 0);
~ConsoleWindow();
public slots:
void updateTimer(void);
public:
QTextEdit *consoleBox;
StdRedirector<> *stdRedirector;
string bufferString;
};
#endif
The StdRedirector class is based on code from this forum post: http://www.qtforum.org/article/24554/displaying-std-cout-in-a-text-box.html
Take a look at the popen() function, it might do what you need.
Then you could pass the FILE * to a QTextStream and work in Qt style with it.
I suggest, rather than showing stdout in GUI, having own console output, which essentially means all messages you want to show to users you are sending to your own output.
This way you can have debug messages and such still available from console, wtih potential errors with connections and whatever that can happen and have fully controlled console output in GUI application. Of course this output can also be outputted to stdout so it is visible in console, but it also allows you to append a prefixs like WARNING LOG NOTICE NO_THIS_WENT_WRONG or whatever you want to show to users as your console entry.

How to use a QFile with std::iostream?

Is it possible to use a QFile like a std::iostream? I'm quite sure there must be a wrapper out there. The question is where?
I have another libs, which requires a std::istream as input parameter, but in my program i only have a QFile at this point.
I came up with my own solution using the following code:
#include <ios>
#include <QIODevice>
class QStdStreamBuf : public std::streambuf
{
public:
QStdStreamBuf(QIODevice *dev) : std::streambuf(), m_dev(dev)
{
// Initialize get pointer. This should be zero so that underflow is called upon first read.
this->setg(0, 0, 0);
}
protected:
virtual std::streamsize xsgetn(std::streambuf::char_type *str, std::streamsize n)
{
return m_dev->read(str, n);
}
virtual std::streamsize xsputn(const std::streambuf::char_type *str, std::streamsize n)
{
return m_dev->write(str, n);
}
virtual std::streambuf::pos_type seekoff(std::streambuf::off_type off, std::ios_base::seekdir dir, std::ios_base::openmode /*__mode*/)
{
switch(dir)
{
case std::ios_base::beg:
break;
case std::ios_base::end:
off = m_dev->size() - off;
break;
case std::ios_base::cur:
off = m_dev->pos() + off;
break;
}
if(m_dev->seek(off))
return m_dev->pos();
else
return std::streambuf::pos_type(std::streambuf::off_type(-1));
}
virtual std::streambuf::pos_type seekpos(std::streambuf::pos_type off, std::ios_base::openmode /*__mode*/)
{
if(m_dev->seek(off))
return m_dev->pos();
else
return std::streambuf::pos_type(std::streambuf::off_type(-1));
}
virtual std::streambuf::int_type underflow()
{
// Read enough bytes to fill the buffer.
std::streamsize len = sgetn(m_inbuf, sizeof(m_inbuf)/sizeof(m_inbuf[0]));
// Since the input buffer content is now valid (or is new)
// the get pointer should be initialized (or reset).
setg(m_inbuf, m_inbuf, m_inbuf + len);
// If nothing was read, then the end is here.
if(len == 0)
return traits_type::eof();
// Return the first character.
return traits_type::not_eof(m_inbuf[0]);
}
private:
static const std::streamsize BUFFER_SIZE = 1024;
std::streambuf::char_type m_inbuf[BUFFER_SIZE];
QIODevice *m_dev;
};
class QStdIStream : public std::istream
{
public:
QStdIStream(QIODevice *dev) : std::istream(m_buf = new QStdStreamBuf(dev)) {}
virtual ~QStdIStream()
{
rdbuf(0);
delete m_buf;
}
private:
QStdStreamBuf * m_buf;
};
I works fine for reading local files. I haven't tested it for writing files. This code is surely not perfect but it works.
I came up with my own solution (which uses the same idea Stephen Chu suggested)
#include <iostream>
#include <fstream>
#include <cstdio>
#include <QtCore>
using namespace std;
void externalLibFunction(istream & input_stream) {
copy(istream_iterator<string>(input_stream),
istream_iterator<string>(),
ostream_iterator<string>(cout, " "));
}
ifstream QFileToifstream(QFile & file) {
Q_ASSERT(file.isReadable());
return ifstream(::_fdopen(file.handle(), "r"));
}
int main(int argc, char ** argv)
{
QFile file("a file");
file.open(QIODevice::WriteOnly);
file.write(QString("some string").toLatin1());
file.close();
file.open(QIODevice::ReadOnly);
std::ifstream ifs(QFileToifstream(file));
externalLibFunction(ifs);
}
Output:
some string
This code uses std::ifstream move constructor (C++x0 feature) specified in 27.9.1.7 basic_ifstream constructors section of Working Draft, Standard for Programming Language C++:
basic_ifstream(basic_ifstream&& rhs);
Effects: Move constructs from the
rvalue rhs. This is accomplished by
move constructing the base class, and
the contained basic_filebuf. Next
basic_istream::set_rdbuf(&sb) is called to install the contained
basic_filebuf.
See How to return an fstream (C++0x) for discussion on this subject.
If the QFile object you get is not open for read already, you can get filename from it and open an ifstream object.
If it's already open, you can get file handle/descriptor with handle() and go from there. There's no portable way of getting a fstream from platform handle. You will have to find a workaround for your platforms.
Here's a good guide for subclassing std::streambuf to provide a non-seekable read-only std::istream: https://stackoverflow.com/a/14086442/316578
Here is a simple class based on that approach which adapts a QFile into an std::streambuf which can then be wrapped in an std::istream.
#include <iostream>
#include <QFile>
constexpr qint64 ERROR = -1;
constexpr qint64 BUFFER_SIZE = 1024;
class QFileInputStreamBuffer final : public std::streambuf {
private:
QFile &m_file;
QByteArray m_buffer;
public:
explicit QFileInputStreamBuffer(QFile &file)
: m_file(file),
m_buffer(BUFFER_SIZE, Qt::Uninitialized) {
}
virtual int underflow() override {
if (atEndOfBuffer()) {
// try to get more data
const qint64 bytesReadIntoBuffer = m_file.read(m_buffer.data(), BUFFER_SIZE);
if (bytesReadIntoBuffer != ERROR) {
setg(m_buffer.data(), m_buffer.data(), m_buffer.data() + bytesReadIntoBuffer);
}
}
if (atEndOfBuffer()) {
// no more data available
return std::char_traits<char>::eof();
}
else {
return std::char_traits<char>::to_int_type(*gptr());
}
}
private:
bool atEndOfBuffer() const {
return gptr() == egptr();
}
};
If you want to be able to more things like seek, write, etc., then you'd need one of the other more complex solutions here which override more streambuf functions.
If you don't care much for performance you can always read everything from the file and dump it into an std::stringstream and then pass that to your library. (or the otherway, buffer everything to a stringstream and then write to a QFile)
Other than that, it doesn't look like the two can inter-operate. At any rate, Qt to STL inter operations are often a cause for obscure bugs and subtle inconsistencies if the version of STL that Qt was compiled with is different in any way from the version of STL you are using. This can happen for instance if you change the version of Visual Studio.

Resources