is ROS nondeterministic ?
Hello Everyone,
I'm developing a code to control a follower rover aiming at keeping a reference distance with a leader rover. I 'm using ROS nodes that communicate using topics. I define a scenario Node which initiate the positions of the two rover for a specific period of time. After that I initiate the positions and the thing is i get different output for the same input. So I was wondering if ROS is nondeterministic or my code is wrong ?
In my case, I associate to each node a C++ class containing two methods init() and run. I have a Leader Node (uncontrolledRobot.cpp), a follower Node (controlledRobot.cpp) and a follower Controller Node along side with a scenario node. This latter determine the simulation duration and then order the two node (leader and follower to start from initial position).
#include<ros/ros.h>
#include<std_msgs/Float64.h>
#include<std_msgs/Int32.h>
#include<std_msgs/Bool.h>
//Start of user code User includes
#include"UncontrolledRobot.h"
//End of user code
//global variables
std_msgs::Float64 posX;
std_msgs::Float64 posY;
std_msgs::Bool startLeader;
std_msgs::Bool stopComputation;
std_msgs::Int32 trajectory;
//Callback function
void myCallbackLeader(const std_msgs::Bool& message_holder)
{
ROS_INFO("received leader restart %d",message_holder.data);
startLeader.data=message_holder.data;
}
void myCallbacktrajectory(const std_msgs::Int32& message_holder)
{
//check for data on topic "trajectory"
ROS_INFO("trajectory value is:%f",message_holder.data);
trajectory.data=message_holder.data;
}
//main program
int main(int argc, char **argv)
{
ros::init(argc,argv,"LeaderNode");//name this node
ros::NodeHandle nh;//node handle
//create subscribers
ros::Subscriber my_subscriber_object1=nh.subscribe("startLeader",1,myCallbackLeader);
ros::Subscriber my_subscriber_object2=nh.subscribe("trajectory",1,myCallbacktrajectory);
//publish outputs;
ros::Publisher my_publisher_object1=nh.advertise<std_msgs::Float64>("posXLeader",1);
ros::Publisher my_publisher_object2=nh.advertise<std_msgs::Float64>("posYLeader",1);
ros::Publisher my_publisher_object3=nh.advertise<std_msgs::Bool>("stopComputation",1);
double sample_rate=1.0;//computing the corresponding update frequency
ros::Rate naptime(sample_rate);//use to regulate loop rate
startLeader.data=true;
stopComputation.data=false;
//trajectory.data=11;
//Start of user code User declaration
UncontrolledRobot theLeader;
//End of user code
while (ros::ok())
{
//Start of user code User code
if (startLeader.data) {
stopComputation.data=true;
my_publisher_object3.publish(stopComputation);
//trajectory.data=1;
theLeader.init();
stopComputation.data=false;
my_publisher_object3.publish(stopComputation);
startLeader.data=false;
}
theLeader.run(posX,posY,trajectory);
//End of user code
my_publisher_object1.publish(posX);
ROS_INFO("posX command =%f",posX.data);
my_publisher_object2.publish(posY);
ROS_INFO("posY command =%f",posY.data);
ros::spinOnce();//allow data update from callback
naptime.sleep();//wait for remainder of specified period
}
return 0;//should never get here, unless roscore dies
}
scenario Node
#include<ros/ros.h>
#include<std_msgs/Float64.h>
#include<std_msgs/Int32.h>
#include<std_msgs/Bool.h>
#include<iostream>
#include<unistd.h>
//Variable declaration
std_msgs::Float64 Kv;
using namespace std;
std_msgs::Bool startLeader;
std_msgs::Bool startFollower;
std_msgs::Bool startObserver;
std_msgs::Bool endObserver;
std_msgs::Bool startComputeD;
int simulationDuration=3900;
std_msgs::Int32 trajectory;
//main program
int main(int argc, char **argv)
{
ros::init(argc,argv,"scenarioNode");//name this node
ros::NodeHandle nh; // node Handle
//Publish set point
ros::Publisher my_publisher_object1=nh.advertise<std_msgs::Float64>("Kv",1);
ros::Publisher my_publisher_object2=nh.advertise<std_msgs::Bool>("startLeader",1);
ros::Publisher my_publisher_object3=nh.advertise<std_msgs::Bool>("startFollower",1);
ros::Publisher my_publisher_object4=nh.advertise<std_msgs::Bool>("startObserver",1);
ros::Publisher my_publisher_object5=nh.advertise<std_msgs::Bool>("startComputeD",1);
//ros::Publisher my_publisher_object5=nh.advertise<std_msgs::Bool>("endObserver",1);
ros::Publisher my_publisher_object6=nh.advertise<std_msgs::Int32>("trajectory",1);
ros::Rate loop_rate(1);
//double sample_rate=10.0;//computing the corresponding update frequency
//ros::Rate naptime(sample_rate);//use to regulate loop rate
//ros::spinOnce();
int tick = 0;
Kv.data=0.7;
trajectory.data=1;
startLeader.data=true;
startFollower.data=true;
startObserver.data=true;
startComputeD.data=true;
//endObserver.data=false;
my_publisher_object2.publish(startLeader);
my_publisher_object3.publish(startFollower);
//my_publisher_object1.publish(Kv);
my_publisher_object4.publish(startObserver);
my_publisher_object5.publish(startComputeD);
my_publisher_object6.publish(trajectory);
// my_publisher_object5.publish(endObserver);
while(ros::ok() && tick<simulationDuration) {
ros::spinOnce();
tick++;
my_publisher_object1.publish(Kv);
my_publisher_object6.publish(trajectory);
/* if (tick%50==0 && tick%100!=0){
trajectory.data=3;
my_publisher_object6.publish(trajectory);
}*/
if (tick%100 == 0) {
startLeader.data=true;
startFollower.data=true;
startObserver.data=true;
startComputeD.data=true;
//endObserver.data=true;
my_publisher_object2.publish(startLeader);
my_publisher_object3.publish(startFollower);
my_publisher_object5.publish(startComputeD);
Kv.data= Kv.data;
trajectory.data=1;
my_publisher_object1.publish(Kv);
my_publisher_object6.publish(trajectory);
ROS_INFO("Kv=: %lf ", Kv);
my_publisher_object4.publish(startObserver);
}
loop_rate.sleep();
}
return 0; //should never get here, unless roscore dies
}
Leader Node:
To explain a little bit: I have two rovers: Leader and follower. My objective is to develop a controller to maneuver the follower aiming at keeping a reference distance between the 2. there is a parameter in the controller noted Kv that needs to be tuned. For start, i suppose that my leader go straight (x++,y++) and Kv=0.7. I want to simulate the response of my controller (the coordinate of the follower) for this value of Kv. Then i want to re-initiate the positions of the two rovers change the value of kv and simulate once again.
thank you for your response .
Asked by Hamza on 2018-12-19 10:58:55 UTC
Comments
Can you describe in more detail how you are setting the positrons of your rovers. From you question or sounds like you're initializing them twice. Can tell us where the positions are stored and how you're updating and reading these positions.
Asked by PeteBlackerThe3rd on 2018-12-19 12:18:00 UTC
I updated the question and putted some code i developed. thanks in advance for your help.
Asked by Hamza on 2018-12-19 12:58:11 UTC
ROS does not guarantee message delivery and does not guarantee ordering between messages delivered on different topics. I cannot tell if either of these will affect your code or not.
Asked by ahendrix on 2018-12-19 16:29:16 UTC
I've had a quick look at your code, and I'm afraid it doesn't make any sense to me. You're using ROS in a very strange way that it was never intended to be used, and I'm honestly not surprised it isn't working. I recommend working through the turtle bot tutorials before continuing.
Asked by PeteBlackerThe3rd on 2018-12-19 19:26:19 UTC
I've refrained from commenting myself as the code is indeed rather convoluted. Perhaps @Hamza can clarify a bit more what it is supposed to do.
Don't explain the code that's there. Describe what you're trying to achieve.
Asked by gvdhoorn on 2018-12-20 03:34:17 UTC
I tried to describe what i want to do above. I hope it is clear. Thanks again for your help.
Asked by Hamza on 2018-12-20 03:58:53 UTC