My setup is: ROS melodic, Ubuntu: 18.04
I want simulate turtlebot3 moving with my own global planner and have been following this tutorial to get started: http://wiki.ros.org/navigation/Tutorials/Writing%20A%20Global%20Path%20Planner%20As%20Plugin%20in%20ROS#Running_the_Plugin_on_the_Turtlebot. The tutorial seem to be made for ROS hydro, but as it was the best source of guidance I could find I hoped it would work.
The error I'm having is:
Failed to create the global_planner/GlobalPlanner planner, are you sure it is properly registered and that the containing library is built? Exception: MultiLibraryClassLoader: Could not create object of class type global_planner::GlobalPlanner as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
To my knowledge I've followed the tutorial as much as possible with a only a few things done differently because I wanted to test it, couldn't do as the tutorial asked, or because I thought it wouldn't impact the results. What I have done differently is:
I use the carrot_planner.h and carrot_planner.cpp files in the tutorial section 1 to test that it works before trying with my own code to avoid confusion about where possible errors come from. It's not 'different' from the tutorial to my knowledge, but figured I'd mention it. They are placed in catkin_ws/src/carrot_planner/src/global_planner/
The ros package I'm working from is in catkin_ws/src and is called the carrot_planner. In the tutorial step 1.3 I use add_library(global_planner_lib src/global_planner/carrot_planner.cpp). Would not imagine it affects the results either.
In section 3 of the tutorial it mentions that 'First, you need to copy the package that contains your global planner (in our case global_planner) into the catkin workspace of your Turtlebot (e.g. catkin_ws).' Since my package was already in catkin_ws/src/ I haven't moved it since I guess I didn't need to.
I've altered the 'move_base.launch' file in '/opt/ros/melodic/share/turtlebot3_navigation/launch/' instead of the 'move_base.launch.xml' in '/opt/ros/hydro/share/turtlebot_navigation/launch/includes/' as there doesn't seem to be a destination '...turtlebot3_navigation/launch/includes/'. There are files in launch, but no includes folder. Maybe that a difference from Hydro to Melodic, I don't know. There may be a whole lot of things that need to be done differently from the tutorial when using Melodic, or with turtlebot3, but I don't know.
I haven't made my own launch file for bringup of the turtlebot, but have instead followed this tutorial (https://emanual.robotis.com/docs/en/platform/turtlebot3/nav_simulation/) to guide me with turtlebot3. After finishing this step in the global planner tutorial 'Save and close the move_base.launch.xml. Note that the name of the planner is global_planner/GlobalPlanner the same specified in global_planner_plugin.xml. Now, you are ready to use your new planner' I tested whether it worked by running: 'roslaunch turtlebot3_gazebo turtlebot3_world.launch' and then I tried running: 'roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/map.yaml' which led to the error I showed above. I have created the map-yaml, so there's no misunderstanding whether that's missing.
I would be very glad for any help, thank you ^^
Edit: My system only had 'navfn' on it, not 'global_planner' or 'carrot_planner', if that makes a difference.
After looking over the code I found a solution. It doesn't make everything work perfectly yet, but seems to solve the immediate problem.
The problem was that in my 'global_planner_plugin.xml' I just used the code provided in the tutorial:
<library path="lib/libglobal_planner_lib">
<class name="global_planner/GlobalPlanner" type="global_planner::GlobalPlanner" base_class_type="nav_core::BaseGlobalPlanner">
<description>This is a global planner plugin by iroboapp project.</description>
</class>
</library>
But in the carrot_planner.cpp file it says:
PLUGINLIB_EXPORT_CLASS(carrot_planner::CarrotPlanner, nav_core::BaseGlobalPlanner)
Changing type="global_planner::GlobalPlanner to type="carrot_planner::CarrotPlanner and then launching turtlebot3 doesn't give the same error anymore.
I am trying to securely clear out a directory using SDelete. I know that this is used from the Command line, but how I would I go about automatically clearing the directory from my C++ code, also using Qt if this has a built any built in functions. I could not find anything with searching and this is my first time doing something like this. Any help would be greatly appreciated, thanks.
It is good that you're not trying to re-create the functionality of SDelete. It would be a LOT of work to do as good as a job as what SDelete does. Invoking the existing application is a wise choice.
Now, on to your question... If you want to use QT, then what you need is something like this:
QString path = QString("sdelete", QStringList() << "Bogus.txt");
QProcess sdelete;
sdelete.start( path );
sdelete.waitForFinished();
That will start the process sdelete with the parameter Bogus.txt and then wait until the application is finished.
More Info: https://doc.qt.io/archives/qt-4.8/qprocess.html#start
Edit from OP : I found that using the following worked for me with the argument being passed in being a QString.
QProcess::execute("sdelete -s path");
I'm attempting to use Qt Creator to develop on Unreal Engine 4 in Linux. I've run into an issue with the debugger: I'm unable to get Qt Creator to use GDB's pretty printers.
Epic has written pretty printers for their custom containers (like their string class) and these work great in GDB. From Qt Creator's Debugger Log, I can see that GDB is registering these printers. In fact, I can even enter a "print " command and the output is formatted nicely. However, entering the variable as an expression in the watch window, all I see is the memory address the FString points at.
Specifically, here is the debugger command issued and the resulting output when I add the FString variable "Filename" to the watch window:
Command:
140python theDumper.fetchVariables({"autoderef":1,"context":"","displaystringlimit":"100","dyntype":1,"expanded":["local","watch","inspect","local.Filename.Data","local.Filename","return"],"fancy":1,"formats":{},"nativemixed":0,"partialvar":"watch.0","passexceptions":0,"qobjectnames":0,"resultvarname":"","stringcutoff":"10000","token":140,"typeformats":{},"watchers":[{"exp":"46696c656e616d65","iname":"watch.0"}]})
<Rebuild Watchmodel 16 # 09:05:19.576 [54836ms] >
Output:
dADJUSTING CHILD EXPECTATION FOR local.Filename
dADJUSTING CHILD EXPECTATION FOR local.Filename.Data
<140python theDumper.fetchVariables({"autoderef":1,"context":"","displaystringlimit":"100","dyntype":1,"expanded":["local","watch","inspect","local.Filename.Data","local.Filename","return"],"fancy":1,"formats":{},"nativemixed":0,"partialvar":"watch.0","passexceptions":0,"qobjectnames":0,"resultvarname":"","stringcutoff":"10000","token":140,"typeformats":{},"watchers":[{"exp":"46696c656e616d65","iname":"watch.0"}]})
>&"python theDumper.fetchVariables({\"autoderef\":1,\"context\":\"\",\"displaystringlimit\":\"100\",\"dyntype\":1,\"expanded\":[\"local\",\"watch\",\"inspect\",\"local.Filename.Data\",\"local.Filename\",\"return\"],\"fancy\":1,\"formats\":{},\"nativemixed\":0,\"partialvar\":\"watch.0\",\"passexceptions\":0,\"qobjectnames\":0,\"resultvarname\":\"\",\"stringcutoff\":\"10000\",\"token\":140,\"typeformats\":{},\"watchers\":[{\"exp\":\"46696c656e616d65\",\"iname\":\"watch.0\"}]})\n"
>~"data=[{iname=\"watch.0\",name=\"0\",numchild=\"0\",valueencoded=\"notaccessible\",value=\"\",},{iname=\"watch.0\",wname=\"46696c656e616d65\",numchild=\"1\",type=\"FString &\",value=\"\",address=\"0x7fffffff76b8\",},],typeinfo=[],partial=\"1\"\n"
>~"\"[{'d_d_ptr': 3, 'cannotBeQObject': 3}, [['locals', 117], ['watches', 837842], ['safePrint', 54]]]\"\n"
>140^done
<Rebuild Watchmodel 16 # 09:05:19.576 [54836ms] >
sFinished retrieving data
(Not sure if the "ADJUSTING CHILD EXPECTATION FOR" lines were for the previous command or this one)
Toggling the "Load system GDB pretty printers" option doesn't seem to have any effect.
Searching the web hasn't yielded much for me so far. Any help would be greatly appreciated!
Edit: oh this is interesting. I did a diff of the output with pretty printing disabled vs enabled. With it enabled, I get:
<23importPlainDumpers on
sStopped at breakpoint 1 (1) in thread 1.
<24-thread-info
>&"importPlainDumpers on\n"
>&"Python Exception <type 'exceptions.AttributeError'> 'function' object has no attribute 'subprinters': \n"
>&"Error occurred in Python command: 'function' object has no attribute 'subprinters'\n"
>23^error,msg="Error occurred in Python command: 'function' object has no attribute 'subprinters'"
Edit 2: Looking into it more, it appears Qt Creator may not support pretty printers that involve using lookup functions. Is this the case?
Okay. It appears Qt Creator expects pretty printers to conform to the structure defined by the PrettyPrinter and SubPrettyPrinter objects, and enforced by the register_pretty_printer() function, defined in gdb's printing.py script and documented here: https://sourceware.org/gdb/onlinedocs/gdb/gdb_002eprinting.html
Unreal's printers do not do this.
However, even if they did, it appears Qt Creator's import code will only import subprinters, not parent pretty printers (refer to importPlainDumpers() in gdbbridge.py). It seems the best way to solve this is to update Unreal's printers to follow the examples I can find of using a function to build 'RegexpCollectionPrettyPrinter's.
I have read this blogpost http://www.ics.com/blog/qt-tips-and-tricks-part-1 and tried to enable plugin debugging as described.
I've put this line in my main.cpp:
qputenv(QT_DEBUG_PLUGINS, 1);
But if I try to compile I'm getting this error:
.../src/main.cpp:14: error: 'QT_DEBUG_PLUGINS' was not declared in this scope
qputenv(QT_DEBUG_PLUGINS, -1);
What is the problem here and how do I have to do it right?
qputenv("QT_DEBUG_PLUGINS", QByteArray("1"));
But I don't get any additional output.
I'm using Qt5.5.1 with QtCreator 3.6 under KUbuntu 15.10.
You're supposed to set env variable from outside your program, not from inside! It's very likely the plugin loading you're interested into already happened by the time you reach that line. Try putting it before creating a Q*Application object.
– peppe
That's it. It was definitely set before plugin loading, but it seems to be important to set it before creating Q*Application as you wrote. Thank you.
– avb
I try use the "GetModuleFileName" to get current "setup.msi" location use mydll.dll in setup.msi installer.
But always give me "c:\windows\system\setup.msi".
Any body know why ? Plx help .
You mention C++ so I'm assuming that you are creating a Type 1 custom action as described here. If this is so, I'm guessing that you are trying to figure out where the install is occurring from so you can reference a file or something. If so, check out the MsiGetProperty function and the OriginalDatabase property. If that doesn't meet your needs checkout the the MsiSourceList* functions starting with MsiSourceListGetInfo.