Rosserial Creation of Subscriber Failed
After running:
rosrun rosserial_python serial_node.py /dev/ttyACM0
I receive these info and error messages (node connects, but can't find subscriber):
[INFO] [1553102815.473901]: ROS Serial Python Node
[INFO] [1553102815.508651]: Connecting to /dev/ttyACM0 at 57600 baud
[ERROR] [1553102817.635874]: Creation of subscriber failed: need more than 1 value to unpack
I am running ROS Kinetic on a 4G/64G LattePanda with Ubuntu 16.04 LTS, 64 bit, kernel 4.12.1-20180417
This is my first time using ROS.
My goal is to use rosserial and the LattePanda's onboard arduino (Arduino Leonardo) to create a subscriber to a custom message format. I have another publisher that is running in a terminal session on the LattePanda. I use the following procedure as setup:
After using:
catkin_make
I see no errors or issues. I then try and build the arduino headers that will be necessary to flash. First, I delete the ros_lib folder in the ~/Arduino/library/ directory. Then:
~/Arduino/libraries$ rosrun rosserial_client make_libraries .
This seems to run properly, giving output in the terminal and recreating the ros_lib folder in the ~/Arduino/libraries/ directory.
After running roscore and my publisher node, the messages are being published properly because I can view them using:
rostopic echo /moveControl
I will say that one of my issues is that after creating the header files for the arduino, when I try and use
#include <beginnner_tutorials/Movement.h>
in the arduino code, I am presented with the following error when I attempt to compile:
movementControl:4:41: error: beginner_tutorials/Movement.h: No such file or directory
compilation terminated.
exit status 1
beginner_tutorials/Movement.h: No such file or directory
This is extra irksome, because I can clearly see that the file and directory do exist. I assumed that this was a problem that could be resolved by exiting and reopening the arduino editor (maybe to refresh libraries?), but that did not solve the issue. The only fix I found was to manually include the absolute filepath as shown in my code below. After doing this, it does compile, but I can't help but feel it must be related to rosserial not being able to see my subscriber on the arduino.
I will say that I have had rosserial working before when I was using a stdmsgs uint16t. This must be an issue with my custom message type.
I am a newbie when it comes to ROS and C++, so I would appreciate any and all help!
All of my files are below:
Movement.msg:
int16 servoVal
int16 motorVal
movementControl.ino:
#define USE_USBCON
#include <ros.h>
#include </home/rosuser/Arduino/libraries/ros_lib/beginner_tutorials/Movement.h>
ros::NodeHandle n;
#include <PololuMaestro.h>
#include <SoftwareSerial.h>
SoftwareSerial maestroSerial(7, 8);
MiniMaestro maestro(maestroSerial);
// Defining upper and lower bounds for servo target values
int16_t servoLowTarget = 4000;
int16_t servoMid = 6000;
int16_t servoHighTarget = 8000;
int16_t servoGroup1 = 6000;
int16_t servoGroup2 = 6000;
// Defining Pins for Motor Drivers
const int IN1=10;
const int IN2=11;
const int ENA=9;
const int IN3=5;
const int IN4=6;
const int ENB=3;
// ######################################################
// void Maestro::setAcceleration ( uint8_t channelNumber,
// uint16_t acceleration )
// ######################################################
// ######################################################
// void Maestro::setSpeed ( uint8_t channelNumber,
// uint16_t speed )
// ######################################################
// ######################################################
// void Maestro::setTarget ( uint8_t channelNumber,
// uint16_t target )
//
// Where target is represented in quarter-microseconds
// ######################################################
void servo_cb( const beginner_tutorials::Movement& cmd_msg ){
servoGroup1 = servoMid + cmd_msg.servoVal;
servoGroup2 = servoMid - cmd_msg.servoVal;
// Setting servos to current target values
maestro.setTarget(0, (uint16_t)servoGroup1);
maestro.setTarget(2, (uint16_t)servoGroup1);
maestro.setTarget(4, (uint16_t)servoGroup2);
maestro.setTarget(6, (uint16_t)servoGroup2);
// Setting motors to current target values
if (cmd_msg.motorVal == 1) Move_Forward(100);
if (cmd_msg.motorVal == -1) Move_Backward(100);
}
ros::Subscriber<beginner_tutorials::Movement> sub("moveControl", servo_cb);
void setup() {
// Setting maestro serial buad rate to 9600 (standard)
maestroSerial.begin(9600);
n.initNode();
n.subscribe(sub);
// Setting servo speed to unlimited
maestro.setSpeed(0, 0);
maestro.setSpeed(2, 0);
maestro.setSpeed(4, 0);
maestro.setSpeed(6, 0);
// Setting servo acceleration to unlimited
maestro.setAcceleration(0,0);
maestro.setAcceleration(2,0);
maestro.setAcceleration(4,0);
maestro.setAcceleration(6,0);
// Setting Pin Modes for Motor Driver
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(ENB, OUTPUT);
}
void loop() {
n.spinOnce();
delay(1);
}
//#######################################################
//#############DEFINING MOTOR FUNCTIONS##################
//#######################################################
void Motor1_Forward(int Speed)
{
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
analogWrite(ENA,Speed);
}
void Motor1_Backward(int Speed)
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
analogWrite(ENA,Speed);
}
void Motor1_Brake()
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,LOW);
}
void Motor2_Forward(int Speed)
{
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
analogWrite(ENB,Speed);
}
void Motor2_Backward(int Speed)
{
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
analogWrite(ENB,Speed);
}
void Motor2_Brake()
{
digitalWrite(IN3,LOW);
digitalWrite(IN4,LOW);
}
void Move_Forward(int Speed)
{
Motor1_Forward(Speed);
Motor2_Forward(Speed);
delay(500);
Motor1_Brake();
Motor2_Brake();
delay(100);
}
void Move_Backward(int Speed)
{
Motor1_Backward(Speed);
Motor2_Backward(Speed);
delay(500);
Motor1_Brake();
Motor2_Brake();
delay(100);
}
//#######################################################
//#######################################################
//#######################################################
command_pub.cpp running on in terminal session on LattePanda:
#include "ros/ros.h"
#include "beginner_tutorials/Movement.h"
#include <sstream>
#include <ncurses.h>
uint16_t servoLowTarget = 4000;
uint16_t servoHighTarget = 8000;
int maxDisplace = 2000;
int main(int argc, char **argv)
{
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
cbreak();
ros::init(argc, argv, "command_pub");
ros::NodeHandle n;
ros::Publisher command_pub = n.advertise<beginner_tutorials::Movement>("moveControl", 1000);
ros::Rate loop_rate(10);
int c = 0;
int currentServoVal = 0;
int currentMotorVal = 0;
beginner_tutorials::Movement command;
while (ros::ok())
{
c = 0;
c = getch();
currentMotorVal = 0;
switch(c) {
case 'q':
printw("quitting...");
endwin();
return 0;
break;
case KEY_RIGHT:
currentServoVal += 200;
break;
case KEY_LEFT:
currentServoVal -= 200;
break;
case KEY_UP:
currentMotorVal = 1;
break;
case KEY_DOWN:
currentMotorVal = -1;
break;
default:
printw("I don't recognize that\n");
}
if (currentServoVal >= maxDisplace) currentServoVal = maxDisplace;
if (currentServoVal <= -(maxDisplace)) currentServoVal = -(maxDisplace);
command.servoVal = currentServoVal;
command.motorVal = currentMotorVal;
command_pub.publish(command);
printw("Current Servo Value: %d\n", (int)currentServoVal);
printw("Current Motor Value: %d\n", (int)currentMotorVal);
refresh();
ros::spinOnce();
loop_rate.sleep();
}
endwin();
return 0;
}
package.xml:
<?xml version="1.0"?>
<package format="2">
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner_tutorials package</description>
<maintainer email="rosuser@todo.todo">rosuser</maintainer>
<license>TODO</license>
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<depend>beginner_tutorials/Movement</depend>
<export>
</export>
</package>
excerpts from CMakeLists.txt:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_message_files(
FILES
Movement.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
CATKIN_DEPENDS message_runtime
find_package(Curses REQUIRED)
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)
add_executable(command_pub src/command_pub.cpp)
target_link_libraries(command_pub ${catkin_LIBRARIES} ${CURSES_LIBRARIES})
add_dependencies(command_pub beginner_tutorials_generate_messages_cpp)
Asked by Booker on 2019-03-20 15:00:07 UTC
Answers
I had the same issue. This worked out for me.
We need a simplified header file for custom messages in Arduino sketches. The usual header files in devel have boost dependencies. We can generate a simplified header file by running the following:
rosrun rosserial_arduino make_library.py path_to_libraries your_message_package
The resources I used: ROS wiki and Ch 7. in Mastering ROS for Robotics Programming
Asked by ajaygunalan on 2022-11-04 08:27:37 UTC
Comments
I have almost the exact same problem. Getting the same error message "Creation of subscriber failed...".
I am trying both a combination of running ROS melodic on Debian stretch 9.8 and ROS kinetic on Ubuntu 16.04.
As is also the case in the question asked I have had success using rosserial_arduino before with both combinations using predefined ROS messages, but when trying to implement a custom message (containing two float64) I was not successful. I have checked that the custom message is valid when I use it without rosserial and I am able to build the Arduino sketch without errors with the custom message.
Therefore I am convinced, that the problem is due to the very combination of rosserial, Arduino and custom message.
Did anyone find a solution to the problem ? Thank you very much!
Asked by Amalie on 2019-05-15 02:31:15 UTC
Hi. Answers like this -- which are not actually answers, but follow-up questions -- have very poor visibility. It would be better to post it as a separate question and then refer back to this one.
Asked by gvdhoorn on 2019-05-15 02:56:58 UTC
Same issue. Works perfectly for standard messages. Only throws "Creation of Sub failed. Need more than 1 values to unpack" for custom messages. Have you found a fix? Would have to change a lot of dependent code to revert to standard messages.
Asked by ringo47 on 2020-09-26 15:35:56 UTC