ros::Publisher: command not found? | ROS Melodic | Ubuntu 18.04 - ubuntu-18.04

I facing an issue while running a .cpp file, cleaner_bot.cpp (shown below) through ros run. Here are the following details:
#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "std_msgs/String.h"
#include <sstream>
ros::Publisher vel_publish;
void move(double speed, double direction, bool is_forward);
int main(int argc, char **argv)
{
ros::init(argc, argv, "Cleaner Bot");
ros::NodeHandle n;
vel_publish = n.advertise<geometry_msgs::Twist>("/turtle/cmd_vel", 10);
move(2.0, 5.0, 1.0);
}
void move(double speed, double distance, bool is_forward)
{
geometry_msgs::Twist vel_msg;
// double time = distance/speed;
if(is_forward)
{
// Setting a random linear velocity in the x direction
vel_msg.linear.x = abs(speed);
}
else
{
vel_msg.linear.x = -abs(speed);
}
vel_msg.linear.y = 0;
vel_msg.linear.z = 0;
vel_msg.angular.x = 0;
vel_msg.angular.y = 0;
vel_msg.angular.z = 0;
// Starting the loop with time, t = 0
double time_prev = ros::Time::now().toSec();
// Current distance is 0
double dist_now = 0;
ros::Rate loop_rate(10);
do
{
vel_publish.publish(vel_msg);
double time_now = ros::Time::now().toSec();
double dist_now = speed * (time_now - time_prev);
ros::spinOnce();
}while(dist_now < distance);
vel_msg.linear.x = 0;
vel_publish.publish(vel_msg);
}
I am receiving this message when I am trying to execute rosrun, however doing catkin_make is not giving me any issues.
Can anyone help find what has been missed? The below is what I am getting after executing rosrun
rosrun turtlesim_custom_cleaner src/cleaner_robot.cpp
/home/autoai/catkin_ws/src/turtlesim_custom_cleaner/src/cleaner_robot.cpp: line 7: ros::Publisher: command not found
/home/autoai/catkin_ws/src/turtlesim_custom_cleaner/src/cleaner_robot.cpp: line 9: syntax error near unexpected token `('
/home/autoai/catkin_ws/src/turtlesim_custom_cleaner/src/cleaner_robot.cpp: line 9: `void move(double speed, double direction, bool is_forward);'
System details:
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic
Package: ros-melodic-ros
Status: install ok installed
Priority: optional
Section: misc
Installed-Size: 14
Maintainer: Dirk Thomas <dthomas#osrfoundation.org>
Architecture: amd64
Version: 1.14.9-1bionic.20210505.012339
Depends: ros-melodic-catkin, ros-melodic-mk, ros-melodic-rosbash, ros-melodic-rosboost-cfg, ros-melodic-rosbuild, ros-melodic-rosclean, ros-melodic-roscreate, ros-melodic-roslang, ros-melodic-roslib, ros-melodic-rosmake, ros-melodic-rosunit
Description: ROS packaging system
Thanks all in advance.

You should not (ros)run the source files of your project but rather the executable created by catkin_make.
For example:
rosrun turtlesim_custom_cleaner cleaner_robot
Where cleaner_robot is the name of your executable which depends on what you have defined in your CMakeLists.txt but in general, you should have something like this in there:
add_executable(cleaner_robot src/cleaner_robot.cpp)
Have a look a the ROS tutorials on creating and running packages/nodes
Writing a Simple Publisher and Subscriber
Examining the Simple Publisher and Subscriber

Related

Starting the debuggee failed: No executable specified, use `target exec'

Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// to generate numbers
void gen_data(int b[], int n)
{
int i;
for (i = 0; i < n; i++)
b[i] = rand() % 101;
}
// to display numbers
void disp_data(int b[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d \n", b[i]);
}
// insert at desired posn
void insert(int b[], int n, int elt, int pos)
{
int i;
for (i = n - 1; i >= pos; i--)
b[i + 1] = b[i];
b[pos] = elt;
}
// delete an elt at given position
void delete (int b[], int n, int pos)
{
int i;
for (i = pos + 1; i < n; i++)
b[i - 1] = b[i];
}
// driver code
int main()
{
int a[100], pos, n = 10, let;
int opt;
system("cls");
gen_data(a, n);
while (1)
{
printf("\n 1- Insert 2-Delete 3-Display 4-quit\n");
scanf("%d %d", &pos, &elt);
insert(a, n, elt, pos);
n++;
break;
case 2:
printf("enter position at which elt to be deleted: ");
scanf("%d", &pos);
delete (a, n, pos);
n--;
break;
case 3:
printf("the numbers are : \n");
disp_data(a, n);
break;
}
if (opt == 4)
break;
} // end while
}
Log:
Active debugger config: GDB/CDB debugger:Default
Building to ensure sources are up-to-date
Selecting target:
Debug
Adding source dir: C:\Users\Ranju\Desktop\you\lab pro\
Adding source dir: C:\Users\Ranju\Desktop\you\lab pro\
Adding file: C:\Users\Ranju\Desktop\you\lab pro\bin\Debug\lab pro.exe
Changing directory to: "C:/Users/Ranju/Desktop/you/lab pro/."
Set variable: PATH=.;C:\MinGW\bin;C:\MinGW;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C;C:\Users\Ranju\AppData\Local\Microsoft\WindowsApps;C:\Program Files\CodeBlocks\MinGW\bin
Starting debugger: C:\Program Files\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname -quiet -args "C:/Users/Ranju/Desktop/you/lab pro/bin/Debug/lab pro.exe"
done
Setting breakpoints
Debugger name and version: GNU gdb (GDB) 8.1
Starting the debuggee failed: No executable specified, use `target exec'.
Debugger finished with status 0
In my case, removing space(s) from the project path resolved the problem. Maybe you should try to change path like this:
"C:/Users/Ranju/Desktop/you/labpro/bin/Debug/lab pro.exe"
I recently had the same issue when starting to use CodeBlocks on Windows10 (C::B version 20.03 in my case). The problem was that I also had MinGW installed long before I installed CodeBlocks and CodeBlocks took the gdb.exe from that path instead of taking it from the MinGW path that was installed within CodeBlocks.
The solution for me was to change the default executable path in Settings -> Debugger... -> GDB/CDB debugger -> Default to the gdb.exe that was installed when I installed CodeBlocks. So: <C::B_installation_path>\MinGW\bin\gdb.exe.
After that change, the problem was solved.
I don't know how relevant this may be, but I seem to have the same or similar problem. See the material at
How do you debug using 'Code::Blocks 20.03' (the "mingw" version)?
especially that after the sentence, I have hopefully made progress towards an answer..
I have now added a proper answer to the above question..
I asume that you have MinGW installed, in the directory C:\MinGW.
Perhaps, AT YOUR OWN RISK, you could try temporarily renaming the folder C:\MinGW to something else, and try running the debugger.
I had MinGW pre-installed, when I installed Code::Blocks 20.03 using codeblocks-20.03mingw-setup.exe ( the 8th April 2021 version , default installation accepted). I also had a problem debugging. There is now a fix for this, which seems quite general, applying even without a pre-installed MinGW, see the answer to the other question ( link provided above ).
The fix involves changing a debugger setting, but in your case, you seem to be trying to use the correct debugger, see the line that you give, which is shown just below
Starting debugger: C:\Program Files\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname -quiet -args "C:/Users/Ranju/Desktop/you/lab pro/bin/Debug/lab pro.exe"
In the above, you appear to be trying to use a debugger, from the directory, C:\Program Files\Codeblocks\MinGW\bin, which seems O.K., rather than one from C:\MinGW\bin, which is where the debugger was, that I was trying to use, see the other question.
However, you may be using something other than the debugger from the directory C:\MinGW.
Whether or not you have MinGW installed in C:\MinGW, you may need to alter some Setting in Code::Blocks.
I also had this problem. I am currently running Code::Blocks 17.12 on Windows 10. In my case, I simply upgraded my compiler to Mingw64 bit. To fix: I changed an entry in the default.conf file located in c:\users\logonname\appdata\roaming\codeblocks
directory. After making a copy of the original file I changed the line corresponding to the old debugger, gdb32.exe to the new file gdb.exe in its new directory. That fixed the problem. This was the default.conf old line, before making my change: <![CDATA[C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb32.exe]]>.

File Finder in C

First of all Sorry for my bad English. I am not native English.
I am going to write a program that list all available logical disk drives. Then ask the user to select a drive. then takes a file extension and searches that file type in given drive (including directories and sub-directories). Program should be able to run on windows xp and onward. It should be single stand alone application. I am not expert in C. I have some hands on C#. i have following questions in this regard.
1. Is there any IDE/Tool in which i can write C# like code that directly compiles to single stand alone application for windows?
2. Can you recommend some libs that i can use state forward for this purpose like using in C#? (I have seen dirent and studying it.)
I coppied some code that i am testing as a startup.
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <tchar.h>
#include<conio.h>
#include<dirent.h>
//------------------- Get list of all fixed drives in char array. only drive letter is get. not path.
// add ":\" to build path.
char AllDrives[26];
DWORD GetAllDrives()
{
int AvlDrives=0;
DWORD WorkState=-1;
//TCHAR DrivePath[] = _T("A:\\"); //Orignal Type
//start getting for drive a:\ to onward.
char DrivePath[] = {"A:\\"};
//http://www.tenouk.com/cpluscodesnippet/getdrivetype.html
ULONG uDriveMask = _getdrives();
if (uDriveMask == 0)
{
WorkState=GetLastError();
printf("\r\nFailed to Get drives. Error Details : %lu", WorkState);
return WorkState;
}
else
{
WorkState=0xFF;
printf("The following logical drives are being used:\n");
while (uDriveMask) {
if (uDriveMask & 1)
{
UINT drvType=0;
drvType = GetDriveType(DrivePath);
if(drvType==3)
{
AllDrives[AvlDrives]= DrivePath[0];
AvlDrives++;
printf("\r\n%s",DrivePath);
}
}
++DrivePath[0]; //Scan to all scanable number of drives.
uDriveMask >>= 1;
}
}
return WorkState;
}
int main(int argc, char* argv[]) {
char DrivePath[]={"C:\\"};
char CurrentDrive[]={"C:\\"};
DWORD Drives=-1;
int d=0;
for( d=0; d<26; d++)
AllDrives[d]=' ';
Drives=GetAllDrives();
if(Drives >0)
{
int Length= sizeof(AllDrives);
for(int x=0; x<26; x++)
{
if(AllDrives[x]!=' ')
{
printf("\r\nFixed Drive : %c",AllDrives[x]);
}
}
}
getch();
}
You can use visual studio compiler to compile C and C++ in Windows, and it is available with its own IDE. When you install visual studio, it will install required libraries also to compile the C/C++ program. There are other IDEs and compilers available compatible with Windows like DevC++,CodeBlocks.

Can't get redis connector to work with g-wan

Did all the hiredis installation
defaulting to make make install etc
Result running g-wan:
Linking hellox.c: undefined symbol: redisConnect
online says linking lib is wrong? how to fix this?
Read how to link libraries with G-WAN. Even with GCC you need to tell the linker what library is in use. G-WAN is not different.
Here my script working on my server :
#include "gwan.h" // G-WAN API
#pragma link "hiredis"
#include "hiredis/hiredis.h"
typedef struct
{
redisContext *rCont;
redisReply *rReply;
} data_t;
int main(int argc, char *argv[])
{
data_t **d = (data_t**)get_env(argv, US_SERVER_DATA);
xbuf_t *reply = get_reply(argv);
u64 start = getus();
const char *hostname = "127.0.0.1";
int port = 6379;
struct timeval timeout = { 1, 500000 }; // 1.5 seconds
if(!d[0]) // first time: persistent pointer is uninitialized
{
d[0] = (data_t*)calloc(1, sizeof(data_t));
if(!d[0])
return 500; // out of memory
d[0]->rCont = redisConnectWithTimeout(hostname, port, timeout);
}
d[0]->rReply = redisCommand(d[0]->rCont,"PING");
xbuf_xcat(get_reply(argv), "PING %s<br>", d[0]->rReply->str);
freeReplyObject(d[0]->rReply);
xbuf_xcat(get_reply(argv), "<hr>%llu µs<hr>", getus() - start);
return 200;
}
You have to get hiredis compiled and copied into your lib directory.

Develop C with multiple main entry points

I used to develop Java project by Eclipse.
A Java project can contain many code files with the main function (the entry point), so we can run each code file which has a main function.
But now I want to develop C project by Eclipse CDT.
In a C project we can have only one main function. Can I have many code files with a main function and run each file just like I would in Java?
P.S.: I don't like to write Make Target for each file by main self
Javas option to have a main in every object is highly irritating and does not make sense to me.
I assume you want to train a bit in c and want to find a way to have all training lessons in one file. Here is an option that would do that for you in a crude way. This would not be reasonable to do as an application but you can use this to execute different options.
To use this you would call your program like 'progname 1'.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int ProgrammingLesson001(void);
int main(int argc, char * argv[])
{
int i;
int option;
int e = 0;
printf("%i\n", argc);
for(i = 0; i < argc; ++i)
{
printf("%s\n", argv[i]);
}
if(2 == argc)
{
option = atoi(argv[1]);
printf("Your Option was '%s' interpreted as %i\n", argv[1], option);
}
else
{
option = 0;
e |= 1;
}
switch(option)
{
case 0:
printf("zero is an error\n");
e |= 1;
break;
case 1:
e |= ProgrammingLesson001();
break;
default:
break;
}
if(0 != e)
{
printf("an error has occureed\n");
}
return e;
}
int ProgrammingLesson001(void)
{
printf("This could behave like a main for training purposes\n");
}
If you spent some time programming in c take a second look at makefiles.
You can create a makefile that will fit all your programs.
This reduces the actual work you need to put into this so much that maintaining the switch construct is harder than creating a new project.
Thank Clifford to fixed my quest and guys who replied
I have solved this problem by myself
Here is my solution:
#!/bin/bash
SourceFile=$1
Path="$(dirname "$SourceFile")"
ParentPath="$(dirname "$Path")"
OutputPath="$ParentPath/bin"
OutputFile="$OutputPath/a.out"
mkdir -p $OutputPath
rm -f $OutputFile
gcc -w $SourceFile -lm -o $OutputFile
$OutputFile
This bash's name is gcc.sh
In eclipse run -> external tools -> external tools configurations -> new a configuration
Location: /home/xxxxx/gcc.sh
Working Directory: (just let it be empty)
arguments: ${resource_loc}
Then you can run C file by your customize command

Live graph for a C application

I have an application which logs periodically on to a host system it could be on a file or just a console. I would like to use this data to plot a statistical graph for me. I am not sure if I can use the live graph for my application.
If this tool is the right one, may I have an example on integrating the external application with the live graph?
this is livegraph link --> http://www.live-graph.org/download.html
I think this can be achieved easiest using Python plus matplotlib. To achieve this there are actually multiple ways: a) integrating the Python Interpreter directly in your C application, b) printing the data to stdout and piping this to a simple python script that does the actual plotting. In the following I will describe both approaches.
We have the following C application (e.g. plot.c). It uses the Python interpreter to interface with matplotlib's plotting functionality. The application is able to plot the data directly (when called like ./plot --plot-data) and to print the data to stdout (when called with any other argument set).
#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void initializePlotting() {
Py_Initialize();
// load matplotlib for plotting
PyRun_SimpleString(
"from matplotlib import pyplot as plt\n"
"plt.ion()\n"
"plt.show(block=False)\n"
);
}
void uninitializePlotting() {
PyRun_SimpleString("plt.ioff()\nplt.show()");
Py_Finalize();
}
void plotPoint2d(double x, double y) {
#define CMD_BUF_SIZE 256
static char command[CMD_BUF_SIZE];
snprintf(command, CMD_BUF_SIZE, "plt.plot([%f],[%f],'r.')", x, y);
PyRun_SimpleString(command);
PyRun_SimpleString("plt.gcf().canvas.flush_events()");
}
double myRandom() {
double sum = .0;
int count = 1e4;
int i;
for (i = 0; i < count; i++)
sum = sum + rand()/(double)RAND_MAX;
sum = sum/count;
return sum;
}
int main (int argc, const char** argv) {
bool plot = false;
if (argc == 2 && strcmp(argv[1], "--plot-data") == 0)
plot = true;
if (plot) initializePlotting();
// generate and plot the data
int i = 0;
for (i = 0; i < 100; i++) {
double x = myRandom(), y = myRandom();
if (plot) plotPoint2d(x,y);
else printf("%f %f\n", x, y);
}
if (plot) uninitializePlotting();
return 0;
}
You can build it like this:
$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot
And run it like:
$ ./plot --plot-data
Then it will run for some time plotting red dots onto an axis.
When you choose not to plot the data directly but to print it to the stdout you may do the plotting by an external program (e.g. a Python script named plot.py) that takes input from stdin, i.e. a pipe, and plots the data it gets.
To achieve this call the program like ./plot | python plot.py, with plot.py being similar to:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
while True:
# read 2d data point from stdin
data = [float(x) for x in raw_input().split()]
assert len(data) == 2, "can only plot 2d data!"
x,y = data
# plot the data
plt.plot([x],[y],'r.')
plt.gcf().canvas.flush_events()
I have tested both approaches on my debian machine. It requires the packages python2.7 and python-matplotlib to be installed.
EDIT
I have just seen, that you wanted to plot a bar plot or such thing, this of course is also possible using matplotlib, e.g. a histogram:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
values = list()
while True:
data = [float(x) for x in raw_input().split()]
values.append(data[0])
plt.clf()
plt.hist([values])
plt.gcf().canvas.flush_events()
Well, you only need to write your data in the given format of livegraph and set livegraph up to plot what you want. If wrote small C example which generates random numbers and dumps them together with the time every second. Next, you just attach the livegraph program to the file. That's it.
Playing around with LiveGraph I must say that its use is rather limited. I still would stick to a python script with matplotlib, since you have much more control over how and what is plotted.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(int argc, char** argv)
{
FILE *f;
gsl_rng *r = NULL;
const gsl_rng_type *T;
int seed = 31456;
double rndnum;
T = gsl_rng_ranlxs2;
r = gsl_rng_alloc(T);
gsl_rng_set(r, seed);
time_t t;
t = time(NULL);
f = fopen("test.lgdat", "a");
fprintf(f, "##;##\n");
fprintf(f,"#LiveGraph test file.\n");
fprintf(f,"Time;Dataset number\n");
for(;;){
rndnum = gsl_ran_gaussian(r, 1);
fprintf(f,"%f;%f\n", (double)t, rndnum);
sleep(1);
fflush(f);
t = time(NULL);
}
gsl_rng_free(r);
return 0;
}
compile with
gcc -Wall main.c `gsl-config --cflags --libs`

Resources