Terminal command in a ROS package is not executed - c++

I have a little problem with a ROS node even if i think that it's mainly a C++ code problem.
What i want to do is using a script that runs in the terminal (Ubuntu 14.04) within a ROS node.
I'm doing this using the system() command code of the C++ language.
This script has to elaborate a .txt file stored locally on my PC; when i use the script by a normal command line method, obviously i have to navigate to the directory where my script lies first, and then i launch the script.
To replying this on my node, i use 2 system() instances to navigate to the directory and then to run the script.
The problem is that it seems that the node "cannot see" the command which tells it to navigate to the correct directory, so, all i can obtain is an error saying: cannot read the text file.
The only way to start the script correctly is to launch the node after i manually navigate to the directory where it lies the script.
I'm posting the code below, maybe I'm writing something bad or there is another problem that i can't see, since i'm a noob in the world of ROS and coding in general. Thank you in advance, i know that maybe it's a stupid question!
Marco
Here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
system("cd ~/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt");
exit(0);
return 0;
}
Note: i tried also without the ~ .
EDIT: now it seems that's running correctly, here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
chdir("/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt >doc.txt");
exit(0);
return 0;
}

Use chdir to change directory. System will create a new shell and execute the cd command. Please refer to this stack overflow post for more information.

As neo pointed out, the first system call is changing the current directory of the system call, but it does not influence the parent's (i.e. your node's) current directory.
But, if I may, you should try to solve this differently. Apart from hardcoding the path being wrong, you generally should not assume to have access to the source folder on runtime (e.g. if you do an install, the source could be anywhere). Instead:
put additional data in a new directory (e.g. 'data')
add an install target
retrieve the runtime path to your package using ros::package::getPath('your_package_name') and use the full path + "/data/test.txt" in your system call

Related

Multiple failed attempts to open a text file in C++

I have been spending the past hour trying to figure out how to display a text document programmatically in c++.
The following is the simple main.cpp code, in which I create a directory "Profiles", and another directory "TestProfile" inside. In Profiles/TestProfile I create a "TestFile" and write "Test data" into it.
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include "Profile.hpp"
#include <stdlib.h>
using namespace std;
int main(int argc, const char * argv[]) {
ofstream fs;
mkdir("/Users/dario/Desktop/Profiles", S_IRWXU);
mkdir("/Users/dario/Desktop/Profiles/TestProfile", S_IRWXU);
fs.open("/Users/dario/Desktop/Profiles/TestProfile/TestFile");
fs << "Test data\n";
string path = "/Users/dario/Desktop/Profiles/TestProfile/TestFile";
system(path.c_str());
return 0;
}
Everything up until line 30 works as expected. The directories are there, and "TestFile" is present with data written.
There are no errors present when compiling, but ./a.out gives me a permission denied
darios-mbp:FMES dario$ g++ -std=c++2a main.cpp
darios-mbp:FMES dario$ ./a.out
sh: /Users/dario/Desktop/Profiles/TestProfile/TestFile: Permission denied
I tried a few approaches.
First, I checked the permissions of the text file using ls -l,
it returned -rw-r--r--, so I used chmod 755. After that, the file permissions said -rwxr-xr-x. When running the same code, ./a.out returned no permission denied and it seems like it worked, but the text file was not opened.
Secondly, after the first approach didn't work, I deleted the directories and ./a.out to recreate the original permission denied issue.
I was getting permission denied as before, and this time I tried changing the ownership or the directory.
sh: /Users/dario/Desktop/Profiles/TestProfile/TestFile: Permission denied
darios-mbp:FMES dario$ chown -R $USER
/Users/dario/Desktop/Profiles/TestProfile/TestFile
darios-mbp:
The command worked, but running the code still did nothing despite no errors.
I tried chmod 755, but again no file was opened.
On previous attempts to fix this issue, after changing the ownership the same way I just explained, I even had an error where it was trying to run the first word of the textfile as a command
Line 1: Test: command not found
Although I was not able to recreate that while writing this.
Perhaps I am doing something completely wrong, but I looked as much as I could for solutions online before writing this post. None of them seemed to work. Perhaps my situation is unique in some way and someone here could help point me in the right direction. I apologize in advance if my post is in any way not to standard (if so, please let me know how I can improve questions for next time).h
I am running the code on xcode
EDIT
Thanks to #Codo for the answer, the following edit did what I was looking for
string path = "/Users/dario/Desktop/Profiles/TestProfile/TestFile";
string cmd = "open -a TextEdit ";
system(cmd.c_str());
I understand that you want to open the created file with an appropriate application. Let's assume the file is /dir/file.
To open a file from the command line / terminal, you would run:
open /dir/file
Or, if you want a specific applications:
open -a TextEdit /dir/file
Also see The macOS open Command.
If you just run:
/dir/file
you would execute the file. That's probably not what you intended. And execution is only possible if the file meets certain criteria like execution rights and in the case of a shell script an appropriate header.
In C++, the system() function executes a command that would be valid on the command line (in the terminal).
Thus, to fix your program, change the line with system() to:
string cmd = "open -a TextEdit ";
cmd += path;
system(cmd.c_str());
And for your next question: Paste code as text, not as image: Why not upload images of code/errors when asking a question?

"windows cannot access the specified device....." error in c++

I am MFC guy working on visual studio 2010 create some executables using visual studio!! but on linux and mac my executables are not working as usual windows!!.
So i decided to use "MinGW" compiler to create executables.
Note:-Please give me one suggestion is that," is minGW is best compiler for cross plateform working ??or any thing else is there??"
I successfully install WinGW compiler on my C drive and start working with following program..
#include <iostream>
using namespace std;
int main ()
{
cout << "Hello ";
return 0;
}
I compile it using following command,
g++ -static-libgcc -static-libstdc++ Main.cpp
I found one executable in same folder with name a.exe :).Working fine:)
But after some time i decide to modified same program in following manner like,
int main ()
{
return 0;
}
I compile it with same command but when i execute it using command line it show me error "Access is denied so i goto that folder and run same executable as "Run as Administrator" it show me one messagebox with the message windows cannot access the specified device path or file. you may not have appropriate permissions
---EDIT--
follwing code is NOT WORKING:-
int main ()
{
int k;
return 0;
}
but this program WORKING :-
int main()
{
int k;
k = 0;
return 0;
}
If you are getting this access denied error, then the most likely cause is that the executable file is open in another process, probably the linker or debugger. Try installing Process Explorer and hit Ctrl+F and type in the name of your .exe. This should show the processes that the .exe file open. Kill those processes (or if you are still debugging, then end debugging first). You then should be able to build again.
Note that this has nothing to do with Microsoft APIs, as in any case you're using gcc.
EDIT: If there are no processes holding the .exe then it may be that there is some other kind of permission problem. Does the .exe file exist? Can you delete the file and rebuild? Another thing to try is run Process Monitor and filter for the name of the .exe -- that may show a regular permission denied error, or perhaps another error such as a sharing conflict.
Note:-Please give me one suggestion is that," is minGW is best compiler for cross plateform working ??or any thing else is there??"
No. And there's nothing else out there.
Use whatever compiler is available on target platform, ensure your code compiles on all of them.
Avoid platform-specific and compiler-specific code at all costs (use cross-platform frameworks).
I successfully install WinGW
There are many different versions of mingw provided by different sites. If you install compiler from mingw.org using mingw-get, it'll probably work. If you install mingw from some other site, it may or may not work.
I compile it using following command,
Use a build systems. cmake, qmake or something similar.
it show me error "Access is denied
Launch process monitor and see after which system call it terminates. It is also possible that your antivirus software interferes with your program, or maybe there's some stray dll in your path or something like that.
Check the permissions for the entire folder in which the executable resides. Trying to 'Run as Administrator' doesn't have any effect if the folder doesn't allow the permissions.
It doesn't have anything to do with your code. This is an environmental problem, something is pretty messed up about the permissions your user account has for one or more of the directories on your hard disk. The generic diagnostic is that the default working directory for the program does not permit read or list access.
A possible starting point would be to use Explorer and right-click the directory where MinGW is installed. Use the Security tab and ensure that your user account has all permissions enabled. Further narrow it down to trying to run the program from the command prompt, using different directories as the default directory.

system() c++ wont run in VirtualBox

I'm trying to compile and run the app, which was created 4 years ago. It was developed for Windows in Embarcadero RAD Studio C++ builder. Now I try to compile and run it in Windows in VirtualBox using the latest version of RAD Studio. I have a system call to another app in my app:
system("dot.exe -Tjpg -o nfa.jpg NFA_graph.txt");
It keeps returning 1 and the file is not created. I also tried
system("Echo %CD% >> z:\log.txt");
and the file is not created. I also tried like this:
FILE *fpipe;
char *command = "Echo %CD% >> z:\log.txt";
char line[256];
if (0 == (fpipe = (FILE*)_popen(command, "r")))
{
perror("popen() failed.");
exit(1);
}
while (fread(line, sizeof line, 1, fpipe))
{
ShowMessage(line);
}
_pclose(fpipe);
And nothing I get. I wonder if the reason of such strange behaviour is that I'm running this all in VirtualBox?
You're not escaping your \ characters. You should use / in file paths, or \\ if you must. In addition, Windows 7 won't let you write to the root directory of a hard drive w/o administrator access.
To determine if a command environment is available, first do this:
if (!system(NULL)) {
// Can't make any system() calls
}
If your command environment is available, then you need to fully specify the path, making sure to escape the \'s like I mentioned above, and don't write anything to a drive's root directory. Also make note that opening files does not default create directories.
No, it's very unlikely. I see few issues with your code: you did not check errno if system() returns 1. It can help you to spot a real problem. Also, all backslashes must be Esc'ed.
I'm suggesting that dot.exe is not in PATH environment variable, that's the reason of the system() failure.

Problem with running c program on mac?

I'm a total beginner in C programming so please bear with me. I have just started today and wanted to write a short program - well at least a small script that would just print out a line of text. Now here's what I did in order to achieve this:
I downloaded vim text editor and wrote this few lines of code:
#include <stdio.h>
int main(void)
{
printf("This is some text written in C \n");
return 0;
}
I saved it as inform.c and compiled it using "cc inform.c" command.
In the end I got a.out file but when I'm trying to run it says:
-bash: a.out: command not found
Can someone tell what I'm doing wrong here and point me in the right direction? Thanks.
Bash can't find your command because the current directory is not usually in the path.
Try:
$ ./a.out
It's a basic one.
on Mac, you need to specify were your executable is.
when you type a.out, the system look for the command in /usr/bin and other synstem binaries folders.
to be more precise type ./a.out
which basically says : "in this directory, command a.out"
you should also add directly the classical signature of main which is :
int main(int argc, char ** argv);

call an exe from within c++ (windows)

I'm using VS2010 and I would like to call an exe file which I've created in another directory.
I've tried the following:
int main(){
system("C:\\Users\\Li\\Desktop\\Debug\\modelExample_4pcs.exe");
return 0;
};
but I get "The system could not find the file specified" error.
I've tried to run the exe file directly from the command line, and it only works when I'm inside its directory.
Could you please tell me how can I run it from a different directory?
(I'm using win7)
Thanks,
Li.
You should try using CreateProcess Windows API funcion: http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
Try opening the file for reading, just to check that you have the path right:
char* filename = "C:\\Users\\Li\\Desktop\\Debug\\modelExample_4pcs.exe" ;
FILE* fp = fopen (filename, "rb") ; // Open for reading, binayr mode
if (fp == 0) {
printf ("Duh! File not found\n") ;
exit (0) ;
}
printf ("File found\n") ;
fclose (fp) ;
// Now try the system call, as before:
system(filename);
What happens?
You should be able to use ShellExecute like so: (adjusting the params sent to ShellExecute for your situation) http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx?ppud=4
HINSTANCE hinst = ShellExecute( NULL, _T("open"), commandLine.c_str(), additionalParams.c_str(), NULL, SW_RESTORE );
if(hinst <= (HINSTANCE)SHELLEXERROR)// see: http://msdn2.microsoft.com/en-us/library/bb762153.aspx for further info on the return values
Now given that you are using Win7, you may be having a privilege issue and you need to run at an elevated level (i.e. administrator) you can test this by opening cmd as admin and running your exe from another directory
and as Steve mentioned above you can certainly use CreateProcess.
HTH,
EB
System() may not be able to find cmd.exe to open your environment.
Try using cmd.exe to execute your app via the /C option.
System("C:\\WINDOWS\\system32\cmd.exe /C \"C:\\Users\\Li\\Desktop\\Debug\\modelExample_4pcs.exe\"");
Try this using CreateProcess. Less (or at least different) environmental dependencies than using system(). At least you will get a nice Win32 error code if this still fails.
http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
Check your path, and make sure you escape all characters: C:\\Users\Li..
Is the error from running the main program, not from launching modelExample_4pcs.exe? Try commenting out the system() call and see if you get the same error.
Your main program is not on the path when you're outside its folder...
Is modelExample_4pcs.exe trying to load another file from the current working folder, and THAT's what's generating the error?
Maybe try chdir() before the call to system().
Just change to the directory first, like you would do from the command prompt:
system("C: && CD \\Users\\Li\\Desktop\\Debug\\ && modelExample_4pcs.exe");