How to use a ROS rviz panel to draw in 3d Scene? - qt

I'm working through the rviz tutorials and am trying to figure out how to use the example code "teleop_panel" to draw in the 3d scene. According to the tutorial this should be possible "A panel in RViz is a GUI widget which can be docked in the main window or floating. It does not show properties in the “Displays” panel like a Display, but it could show things in the 3D scene." But I can't figure out how to modify the source code to actually inject data into the 3d scene (like how the IMUDisplay plugin works).
My use case is that I would like to have a way to have some form of rich qt panel (with controls, indicators, etc) that can connect to other ROS topics and draw in the main 3d scene. I don't believe this is possible with the other options (such as a Display plugin) but I could be wrong.

When starting from the teleop_panel plugin tutorial, add the following members to the TeleopPanel class:
Ogre::SceneManager* scene_manager_;
Ogre::SceneNode* childScene;
rviz::MovableText* helloWorldText;
Next add the following code to the onInitialize() method:
scene_manager_ = vis_manager_->getSceneManager();
childScene = scene_manager_->getRootSceneNode()->createChildSceneNode();
helloWorldText = new rviz::MovableText("Hello World!");
childScene->attachObject(helloWorldText);
helloWorldText->setColor(Ogre::ColourValue::Red);
helloWorldText->setCharacterHeight(2);
helloWorldText->setVisible(true);
And finally to clean up add the following destructor:
TeleopPanel::~TeleopPanel() {
// Destroy the child scene node since we don't need it anymore.
scene_manager_->destroySceneNode(childScene);
}
Now when you load the panel you should see "Hello World!" at 0.0 in the 3D scene.

Related

qt layout()->setSizeConstraint

I have a problem with the layout () in Qt 5.
I want to make a dynamic variable dialog.
![enter image description here][1]
Below is the code for the constructor:
SortDialog :: SortDialog (QWidget * parent)
     : QDialog (parent)
{
     setupUi (this);
     SecondaryGroupBox-> hide ();
     TertiaryGroupBox-> hide ();
     layout () -> setSizeConstraint (QLayout :: SetFixedSize);
     setColumnRange ('A', 'Z');
}
The project is built successfully, but when you start receiving a signal from the operating system.
Signal: SIGSEGV
Purpose: Segmentation fault
If you delete a row
layout () -> setSizeConstraint (QLayout :: SetFixedSize);
The program works.
Please, help me.
P.s.:This is an example from the book c++ GUI Programmming with Qt 4 (page 31)
I was having the same problem.
I just solved it.
Probably you don't want the answer after two years, but I really want to write about this somewhere, because there is nothing about this little issue on the web.
The problem was that Qt Designer didn't generate code to set dialog's layout.
I just opened ui_sortdialog.h and found that out of SortDialog a widget was created. Than with this widget a layout would be created. The layout is called gridLayout_4, and every widget and layout of the form are added to this one. When I added to function retranslateUi line SortDialog->setLayout(gridLayout_4); everything worked. Generated code created layout and did everything what needed to be done, but it left SortDialog without any reference to the layout, therefore layout() returned zero.
That's because you didn't create a layout.
Go back to designer and click the form and choose lay out in grid.
If you don't do this, the layout would be 0 and the program will crash.
You have to create a layout, like QVBoxLayout.
QVBoxLayout *layout = new QVBoxLayout;
layout->setSizeConstraint (QLayout :: SetFixedSize);
setLayout(layout);
I fixed this with changing in Designer Form. Make sure that the layout in the Qt Designer is good. Especially "Form -> Adjust Size" at the end. (in the book page 33; creating a "Form-> Lay Out in a Grid"). Use the original code from the book.

Next and previous control button in winAPI to go to next page (c++)

I am creating an winAPI application in c++ I have a photo in preview pane and I want to create two buttons NEXT and PREVIOUS on clicking them I will go to the next page .
Could you please give me the idea how to do that in c++ ??
Do I need to use QT libraray or it can be done using the in built function of WinAPI like -
HWND hwndButton1 = CreateWindow(L"BUTTON",L"NEXT",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,550,800,100,30,m_hwndPreview,(HMENU)buttonid1,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
HWND hwndButton2 = CreateWindow(L"BUTTON",L"PREVIOUS",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,650,800,100,30,m_hwndPreview,(HMENU)buttonid2,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
and then using WM_COMMAND for both the button clicks.
Am I going right?
I just want my API application work like a .pdf extension file...as in PDF files we have up and down arrow and on clicking upon them we can go to the next page..In winAPIc++ I couldn't find any such arrow function.. please tell me if there is any such arrow up/down function present to go to next page (because I am very less interested in creating NEXT and PREVIOUS button using createwindow function.. It looks odd).
You have not mentioned what tools you are using, so we don't know if you have a resouce editor. You should research that in a forum appropriate for the tools. If you think writing one line of code to create a button is "very complicated" then you need a better tool.
If you do not want the buttons to appear on top of the picture then you need another place to put them. One common possibility is a toolbar. It is a strip for buttons along the top or bottom of the main window:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760435(v=vs.85).aspx
With a resource editor you can draw an arrow on the button. Without a resource editor you can set the button text to a unicode arrow:
SetWindowText(hwndButton1, L"\x25bc"); // down arrow, use 25b2 for up arrow
Most buttons (and other controls) are created using a resource editor, placing the controls on a dialog template or a toolbar resource. If you do that Windows will create the buttons when you create the dialog or toolbar. This method is much preferred because Windows will adjust the size of the buttons as required for the screen settings in use.
If you can't do that you must use CreateWindow as you are doing.
Finally it is done.. I have created the buttons neither using Qt or nor using any createWindowEx..The best and easy approach to follow is resource editor ...just put some button on dialog and use IDD_MAINDIALOG (in my case)
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this);
and then
BOOL CALLBACK AMEPreviewHandler::DialogProc(HWND m_hwndPreview, UINT Umsg, WPARAM wParam, LPARAM lParam)
{
switch(Umsg) // handle these messages
{ .........
}
....
}
and thats done. Very easy task.

OpenSceneGraph and Multiple Viewers

I'm using OpenSceneGraph and Qt to develop a simulation software. Simulations can involve multiple bots in the same virtual world. My requirements for views are as follows:
Ability to show static world cameras
Ability to show bot cameras
Ability to move these views around and/or stack them
To accomplish these tasks, I have made an 'OSGWidget' that uses an Osg Viewer to render the scene inside a QGLWidget. This OSGWidget is in turn put inside a QDockWidget that can be moved around and/or stacked, fulfilling that requirement.
The problem is that when using multiple singular viewers to render the same scene in different widgets, I get strange render behavior. Namely, textures do not display properly or sometimes even at all.
I have looked around SO and the OSG forums and while people have had similar problems, the only responses I have seen have suggested switching to an Osg CompositeViewer. For my purposes, I would like to avoid using that as it breaks my desired requirement of movable and stackable widgets rendering the same scene.
Is this an intractable situation that just isn't easily handled by Osg? I have seen several posts that say this is not how OSG is 'supposed to work' but they haven't really provided facts to support that claim. Has anyone done something similar or have any ideas/insight? I can provide code snippets if needed, but as this might just be a contradiction to Osg's ideology I will wait to get some responses.
Thanks to some help from the comments and from a couple other sites, I was able to successfully get the behavior I wanted from CompositeViewer.
Basically, all OSG Views go through my "WidgetDriver" which contains a CompositeViewer.
class OsgWidgetDriver {
public:
void init() {
compositeViewer = new osgViewer::CompositeViewer;
compositeViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
compositeViewer->setReleaseContextAtEndOfFrameHint(false);
}
void start() {
initialized = true;
}
void stop() {
compositeViewer->stopThreading();
compositeViewer->setDone(true);
}
void updateFrame() {
if (initialized)
compositeViewer->frame();
}
void addView(osgViewer::View *view) { compositeViewer->addView(view); }
bool isInitialized() { return initialized; }
protected:
bool initialized;
osgViewer::CompositeViewer *compositeViewer;
};
Then, whenever I make a new Qt OSG Widget, I hand the osg::View off to the driver. I let the driver update the render window, while Qt can still update the QWidget accordingly. It even allows me to place the widget in a QDockWidget so I can move them around and stack them as needed.
Some final notes on the process if anyone else wants to do this:
You will very likely run into weird texture display problems when multiple OSG Viewers are looking at one scene. If that happens, use the osgUtil::Optimizer::TextureVisitor to set all textures to "UnrefImageAfterApply = false". This will allow proper texture displays across multiple osg::View instances.
The CompositeViewer options I set above, threading model to SingleThreaded and releaseContextAtEndOfFrame to false, are necessary if you want a single thread acting upon multiple views. If you use a widget driver like I did, you will want to do this.

Flex - How to get the parent of a custom grid column filter editor and open a pop up window?

I am trying to figure out how to open a pop up window in my Air application, in a secondary Window, instead of the main application window.
I am using the ReusableFX components, which include a custom DataGrid with filtering and other capabilities. The filtering feature displays a pop up window via PopUpManager when you click on the top of a column in the grid.
PopUpManager.addPopUp(this, FlexGlobals.topLevelApplication as DisplayObject);
The problem is that the pop up window opens in the main application - I am assuming because of the 'topLevelApplication' reference.
So, I need a way to open this window in the current Air "s:Window".
I am assuming I need a way to walk up : this.parent.parent or this.owner.owner - though I have tried that and it did not seem to work (it said null reference).
OR, is there a way to get the current top most window / component (NOT the main application / window)?
Update:
I decided to create a new project for the component, and add in the Air libraries. Now I am able to access the "NativeApplication.nativeApplication.activeWindow" call. That gives me the correct Air window. However, it does not seem to be working:
PopUpManager.addPopUp(this, NativeApplication.nativeApplication.activeWindow as DisplayObject);
My popup does not appear. I am assuming because "activeWindow" is not actually a DisplayObject? (so how do I get the DisplayObject if that's the case?)
Update:
Could it be that I am a victim of this adobe bug? (found here originally)
Well, I came up with some changes that seem to work, though there is probably a much cleaner way to do this - I was just not able to figure a way to get a reference to the current air application window except this way (this is using the ReuableFX custom flex component by the way):
First, in my custom DataGridColumn component, I added a public property
public var pApp:Object;
Next, I modified the DropDownFilterHeaderRenderer (extends HBox , implements IListItemRenderer), showFilterDropDown method and right before it calls dropDown.startEdit(column); , added:
column.pApp = parentApplication;
Finally, I modified DropDownFilterEditor (which extends FilterEditorBase), the method startEdit(column:MDataGridColumn) (the previous PopUpManager was calling FlexGlobals.topLevelApplication, which is not the correct window when opening a s:Window in an Air native application:
var editorInstance:Object = _editor.parent;
var columnInstance:Object = editorInstance.column;
var parAppInstance:Object = columnInstance.pApp;
PopUpManager.addPopUp(this, parAppInstance as DisplayObject);

Transparency of QDeclarativeView containing QML on top of a QWidget playing a video (using either phonon or libvlc)

I am currently developing a video player.
The GUI as the topmost layer is written in QML. It should be transparent to lower layers. It contains control elements, some Lists etc., It's displayed using a QDeclarativeView.
Description
QDeclarativeView *upperLayer = new QDeclarativeView(this);
upperLayer->setSource(QUrl("/home/projects/QtVideo/qml/videoControl.qml"));
upperLayer->setStyleSheet(QString("background: transparent");
upperLayer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
uperLayer->showFullScreen();
The layer underneath is a QWidget: I use the libvlc to display the video content
in this widget.
Reason: I am receiving MPEG-TS, which can not be decoded by phonon, afaik. Therefore I need the libvlc to decode the incoming *.ts stream and put the output onto the display.
QWidget *lowerLayer = new QWidget(this);
lowerLayer.setGeometry(QString("background: red"));
QUrl* url = new QUrl("file:///home/projects/QtVideo/video.ts");
libvlc_instance_t*vlcObject;
libvlc_media_t*vlcMedia;
libvlc_media_player_t*vlcPlayer;
vlcPlayer = NULL;
if(vlcObject = libvlc_new(argc, argv)) == NULL)
{
printf("Not able to initialize";
exit(1);
}
if(vlcPlayer && libvlc_media_player_is_playing(vlcPlayer))
{
libvlc_media_player_stop(vlcPlayer);
}
vlcPlayer = libvlc_media_player_new(vlcObject);
vlcMedia = libvlc_media_new_location(vlcObject, url.toString().toUtf8().constData());
libvlc_media_player_set_media(vlcPlayer, vlcMedia);
#if defined(Q_OS_MAC)
libvlc_media_player_set_nsobject(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_UNIX)
libvlc_media_player_set_x_window(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_WIN)
libvlc_media_player_set_hwnd(vlcPlayer, lowerLayer->winId());
#endif
libvlc_media_player_play(vlc_player);
Both Elements, the QDeclarativeView and the QWidget
are embedded in a QMainWindow, lowerLayer created before the upperLayer,
upperLayer Transparent to the lowerLayer.
The Problem:
As long as the lowerLayer is displaying static elements such as a picture, or some colored shapes, everything works fine, full transparency and functionality.
As soon as I start displaying a video, such as the described *.ts using the libvlc OR some random video using the Phonon::VideoPlayer, the parts of the upperLayer which are above the video parts of the lowerLayer are displayed in the color of the lowerLayer(default: gray), the parts of the upperLayer which are positioned above parts of the lowerLayer or others which do not contain video elements are displayed in correct behaviour.
Question:
Is there any posibility and if, how, to get the upperLayer transparent, even if there is a video playing?
Are you still fighting with this issue? I, sadly, do not have a satisfying answer for you. The best I can do is point you to reasons why it doesn't work:
http://lists.trolltech.com/qt-interest/2007-02/thread01061-0.html
See Message #4 in the link above.
I have tried many different methods to get transparent painting over a video (specifically Phonon::VideoPlayer) using Qt. The only method I've found so far, is to set the overlaying QWidget as a toolTip doing something like
pWidget->setWindowFlags(Qt::ToolTip)
Depending on what exactly you're wanting to do this may be sufficient, but (in my opinion) it's a hack at best. I'm actively struggling with this issue and if I can find some sort of solution, I'll be sure to post it here.
Best of luck.
you're using direct rendering (by passing the wid of the widget) which draws the video overtop at that geometry:
libvlc_media_player_set_x_window
you need to use offscreen rendering and draw that to your qwidget. this can be done with an opengl context (complicated) or using the callback methods available in libvlc.
if you use the display callback (libvlc_video_display_cb) libvlc will also generate lock/unlock methods also, if you need. in this method libvlc will expect some parameters to be set such as canvas geometry and pixel format.
that said, phonon has a libvlc backend which might help, but may still use direct rendering depending on some factors..

Resources