Rosserial Arduino Moveit "joint_states" subscriber callback never called
Hello,
I have followed the tutorial here and successfully managed to follow all steps right to the end (with a custom URDF) - however nothing happens when I execute a Moveit plan.
I have an Arduino Mega interfacing Moveit with my simple 6 dof arm, running the code below. I have placed a nh.loginfo() line in the loop, and a line in the JointsCallback(). I can see in the terminal running rosserial the "Loop" info, but not the "Callback called", which indicates the callback never gets called. I have checked with rostopic echo jointstates that the topic gets published to just fine. Finally, when I subscribe to a dummy topic in the Arduino code, say following the Blink tutorial of rosserial, the callback gets called as soon as a message is published... Yet I do the same things when subscribing to jointstates ! What is wrong with my joint_states subscriber?
I do exactly this: - 1st terminal: roscore - 2nd terminal: source ~/Documents/catkinws/devel/setup.bash, then rosrun rosserialpython serialnode.py _port:=/dev/ttyUSB0 _baud:=115200 - 3rd terminal: source ~/Documents/catkinws/devel/setup.bash, then roslaunch simple6dofarmconfig demo.launch rviztutorial:=true
Arduino code: #include "Arduino.h"
#include <Servo.h>
#include <ros.h>
#include <sensor_msgs/JointState.h>
#define BAUDRATE 115200
#define ATTACH_DELAY 10
enum {
HIP = 0,
SHOULDER, //Shoulder has to be before elbow in the joint states message
ELBOW,
FOREARM,
WRIST,
TOOL_GRIP,
CLAW, //First one of the claw joints has to be the actuator, the other ones will be ignored.
N_JOINTS
};
//Pins
unsigned char const jointPin[N_JOINTS] = {
8,
4,
2,
10,
12,
6,
14
};
unsigned char const jointNeutral[N_JOINTS] = {
95, //Centred
37, //arm vertical
45, //crank perpendicular to arm
95, // hand movement in arm plane
90, //tool grip axis concentric to forearm
90, //A prendre en compte au montage de l'outil, pince dans le plan du bras
90 //TBC
};
//1 if directions identical between angles sent to servos directly and coordinate system in MoveIt, -1 otherwise
char const jointDirSign[N_JOINTS] = {
1, //TBC
1, //TBC
1, //TBC
1, //TBC
-1, //TBC
1, //TBC
1 //TBC
};
Servo joints[N_JOINTS];
ros::NodeHandle nh;
void JointsCallback(const sensor_msgs::JointState& cmd_msg){
float jointAngles[N_JOINTS];
nh.loginfo("Callback called");
for(unsigned int i = 0 ; i < N_JOINTS ; ++i) {
jointAngles[i] = RadiansToDegrees(cmd_msg.position[i]);
//Special processing for elbow: parallel mechanism actuator angle from joint angle
if(i == ELBOW) {
float elbowShoulderOff = -0.0028*pow(jointAngles[ELBOW],2)-0.7927*jointAngles[ELBOW]+77.845; //Obtained from ADAMS
float shoulderAngleFromNeutral = jointAngles[SHOULDER]-jointNeutral[SHOULDER];
joints[i].write(jointNeutral[ELBOW]+jointDirSign[ELBOW]*(shoulderAngleFromNeutral+elbowShoulderOff));
}
else {
joints[i].write(jointNeutral[i]+jointDirSign[i]*jointAngles[i]);
}
}
}
ros::Subscriber<sensor_msgs::JointState> jointsCallback("joint_states", &JointsCallback);
void setup(){
nh.getHardware()->setBaud(BAUDRATE);
nh.initNode();
for(unsigned int i = 0 ; i < N_JOINTS ; ++i) {
joints[i].attach(jointPin[i]);
delay(ATTACH_DELAY);
joints[i].write(jointNeutral[i]);
}
nh.subscribe(jointsCallback);
delay(1000);
}
void loop(){
nh.loginfo("Loop");
nh.spinOnce();
}
inline float RadiansToDegrees(float position_radians)
{
return position_radians * 57.2958;
}
Thanks for your help, Regards
Asked by argargreg on 2020-01-22 13:52:18 UTC
Answers
In the end, I tried subscribing to move_group/fake_controller_joint_states and it worked.. The mystery is still unsolved as to why subscribing to joint_states, which is also valid because I can see the messages using rostopic echo joint_states, does not work.
Asked by argargreg on 2020-01-23 10:05:48 UTC
Comments
At the end were you able to use the FollowJointTrajectory
with rosserial ?
Asked by jkoubs on 2022-12-08 22:42:44 UTC
Comments
JointState
messages can be big, and the default buffer size for Arduinos withrosserial
is not. That could lead to your "dummy message" getting across perfectly fine (as it's small) and aJointState
message never making it.I don't use Arduinos, so I would suggest to search this site for
arduino buffer size
or similar keywords. Use Google, and addsite:answers.ros.org
at the end of the query.Additionally:
JointState
messages are intended to convey state, not setpoints. You seem to want to use them for the latter, which goes against their semantics.Finally: I don't know how often
loop()
is called (ie: what it's period is), but I often see people here on the forum having difficulties with Arduinos and loop rates when they don't sleep or delay for at least a little while each iteration. You may want to look into that as well.Asked by gvdhoorn on 2020-01-22 14:50:02 UTC
Thank you for your answer. I'm only getting started with ROS and MoveIt, and the FollowJointTrajectory interface seems much more complex than simply subscribing to the joint_states topic published by the FakeRobotController - so I started with that. Actually I had already tried playing with the input buffer, and the terminal running rosserial displays an error message if the message is too big for the input buffer so it was not that (although it was indeed my first lead as well). I have tried adding delays in the loop as well without success. In the end, I tried subscribing to move_group/fake_controller_joint_states and it worked, but I still don't understand why subscribing to joint_states, which is also valid because I can see the messages using rostopic echo joint_states, does not work.
Asked by argargreg on 2020-01-23 10:05:15 UTC