ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Need Help Figuring Out Library "ncurses" [closed]

asked 2014-08-27 16:28:58 -0600

K. Zeng gravatar image

updated 2014-08-27 16:48:59 -0600

Hi everyone, I am using ROS Indigo in conjunction with Gazebo 2.2.3 on Ubuntu 14.04. I'm trying to set up my keyboard teleop program so that it will accept a series of commands without me having to press the Enter key every time I type in a command. I installed the ncurses library and have added the following line to my package's package.xml:

  <build_depend>ncurses++</build_depend>
  <run_depend>ncurses++</run_depend>

I've also added the following lines to my CMakeLists.txt:

find_package( PkgConfig REQUIRED )
pkg_check_modules ( ncurses++ REQUIRED ncurses++ )
add_executable(odg_control_keyboard_august_26 src/odg_control_keyboard_august_26.cpp)
target_link_libraries(odg_control_keyboard_august_26 ${catkin_LIBRARIES})
target_link_libraries(odg_control_keyboard_august_26 ${ncurses++_LIBRARIES})
add_dependencies(odg_control_keyboard_august_26 ${catkin_EXPORTED_TARGETS})

My code looks like the following:

#include "ros/ros.h"
#include <gazebo_msgs/ApplyJointEffort.h>
#include <gazebo_msgs/GetModelState.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include "ncurses.h"
using namespace std;

int main (int argc, char **argv)
{
  //Initial setup
  ros::init(argc,argv,"odg_control_keyboard_august_26");
  ros::NodeHandle n;
  ros::Duration dur = ros::Duration(5);
  initscr();
  cbreak();
  noecho();
  keypad(stdscr, TRUE);
  //This client will handle all actions relating to getting the state of the model. It will come into play in the loop.

  //This client will handle moving the model.
  ros::ServiceClient clientMove = n.serviceClient<gazebo_msgs::ApplyJointEffort>("/gazebo/apply_joint_effort");
  gazebo_msgs::ApplyJointEffort applyjointeffort[4];
  applyjointeffort[0].request.joint_name = "left_front_wheel_hinge";
  applyjointeffort[1].request.joint_name = "right_front_wheel_hinge";
  applyjointeffort[2].request.joint_name = "left_rear_wheel_hinge";
  applyjointeffort[3].request.joint_name = "right_rear_wheel_hinge";
  applyjointeffort[0].request.duration = dur;
  applyjointeffort[1].request.duration = dur;
  applyjointeffort[2].request.duration = dur;
  applyjointeffort[3].request.duration = dur;

  int ch = getch();
  while(ch != KEY_BACKSPACE)
  {
    int ch = getch();
    switch (ch)
    {
    case KEY_UP:
      applyjointeffort[0].request.effort = 3;
      applyjointeffort[1].request.effort = 3;
      applyjointeffort[2].request.effort = 3;
      applyjointeffort[3].request.effort = 3;
      clientMove.call(applyjointeffort[0]);
      clientMove.call(applyjointeffort[1]);
      clientMove.call(applyjointeffort[2]);
      clientMove.call(applyjointeffort[3]);
    case KEY_LEFT:
      applyjointeffort[0].request.effort = -2.7;
      applyjointeffort[1].request.effort = 3;
      applyjointeffort[2].request.effort = -2.7;
      applyjointeffort[3].request.effort = 3;
      clientMove.call(applyjointeffort[0]);
      clientMove.call(applyjointeffort[1]);
      clientMove.call(applyjointeffort[2]);
      clientMove.call(applyjointeffort[3]);
    case KEY_DOWN:
      applyjointeffort[0].request.effort = -3;
      applyjointeffort[1].request.effort = -3;
      applyjointeffort[2].request.effort = -3;
      applyjointeffort[3].request.effort = -3;
      clientMove.call(applyjointeffort[0]);
      clientMove.call(applyjointeffort[1]);
      clientMove.call(applyjointeffort[2]);
      clientMove.call(applyjointeffort[3]);
    case KEY_RIGHT:
      applyjointeffort[0].request.effort = 3;
      applyjointeffort[1].request.effort = -2.7;
      applyjointeffort[2].request.effort = 3;
      applyjointeffort[3].request.effort = -2.7;
      clientMove.call(applyjointeffort[0]);
      clientMove.call(applyjointeffort[1]);
      clientMove.call(applyjointeffort[2]);
      clientMove.call(applyjointeffort[3]);
    case KEY_BACKSPACE:    
      printf("Quitting now!\n");
      break;
    default:
      printf("Invalid input!\n");
    }
  }
  endwin();
}

However, when I try to compile it with catkin_make, I end up with the following errors:

odg_control_keyboard_august_26.cpp:(.text+0x10c): undefined reference to `initscr'
odg_control_keyboard_august_26.cpp:(.text+0x111): undefined reference to `cbreak'
odg_control_keyboard_august_26.cpp:(.text+0x116): undefined reference to `noecho'
odg_control_keyboard_august_26.cpp:(.text+0x11d): undefined reference to `stdscr'
odg_control_keyboard_august_26.cpp:(.text+0x12a): undefined reference to `keypad'
odg_control_keyboard_august_26.cpp:(.text+0x27b): undefined reference to `stdscr'
odg_control_keyboard_august_26.cpp:(.text+0x283): undefined reference to ...
(more)
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by K. Zeng
close date 2014-08-28 15:21:45.793891

2 Answers

Sort by ยป oldest newest most voted
3

answered 2014-08-27 16:58:38 -0600

William gravatar image

I've never used ncurses++ before, but I would guess that ${ncurses++_LIBRARIES} is actually empty for some reason. Have you tried using pkg-config directly on the terminal to check the output from ncurses++ or have you tried printing out the value in ${ncurses++_LIBRARIES} with something like message("ncurses++_LIBRARIES: ${ncurses++_LIBRARIES}")?

Another thing to do is to put VERBOSE=1 at the beginning of the command you use to build, which will out the entire call to c++, which will show you what -l and -L flags are being passed. You can then make sure ncurses++ is in that list.

Something else to try is to check for and set the library dirs from pkg_config, something like link_directories(${ncurses++_LIBRARY_DIRS}) in cmake.

edit flag offensive delete link more

Comments

I ran the VERBOSE=1 method you suggested. "ncurses++" only showed up once as "-lncurses++" as part of this "list":

/usr/bin/c++       CMakeFiles/odg_control_keyboard_august_26.dir/src/odg_control_keyboard_august_26.cpp.o  -o /home/peter/catkin_ws/devel/lib/odg_control/odg_control_keyboard_august_26 -rdynamic /opt/ros/indigo/lib/libroscpp.so -lboost_signals -lboost_filesystem /opt/ros/indigo/lib/librosconsole.so /opt/ros/indigo/lib/librosconsole_log4cxx.so /opt/ros/indigo/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex /opt/ros/indigo/lib/libxmlrpcpp.so /opt/ros/indigo/lib/libroscpp_serialization.so /opt/ros/indigo/lib/librostime.so -lboost_date_time /opt/ros/indigo/lib/libcpp_common.so -lboost_system -lboost_thread -lpthread -lconsole_bridge -lncurses++ -Wl,-rpath,/opt/ros/indigo/lib

I'm not sure exactly how to run the first and third methods you suggested.

K. Zeng gravatar image K. Zeng  ( 2014-08-27 17:24:38 -0600 )edit

For message("ncurses++_LIBRARIES: ${ncurses++_LIBRARIES}"), I know it's not a console command, so where exactly should it go? Also, adding link_directories(${ncurses++_LIBRARY_DIRS}) to CMakeLists.txt didn't help.

K. Zeng gravatar image K. Zeng  ( 2014-08-27 17:28:31 -0600 )edit

You should be able to do pkg-config --libs ncurses++ to see the pkg-config contents. Both the message(...) and link_directories(...) would go in the CMakeLists.txt. The link_directories(...) call would only help if the library -lncurses++ is not on the standard library path.

William gravatar image William  ( 2014-08-27 18:05:09 -0600 )edit

I just ran catkin_make with VERBOSE=1 as well as putting those two lines in CMakeLists.txt. The output was the same as before, and ncurses++ only showed up in the same place as last time. Also, pkg-config --libs ncurses++ showed -lncurses++ as the only output. I think you might be right about ${ncurses++_LIBRARIES} being empty.

K. Zeng gravatar image K. Zeng  ( 2014-08-27 18:35:34 -0600 )edit
0

answered 2014-08-28 15:21:08 -0600

K. Zeng gravatar image

I got some help from my boss. I ended up reverting to a version CMakeLists.txt before I made the changes I said in the original questions. I typed in the following lines at the end of CMakeLists.txt:

find_package( PkgConfig REQUIRED )
pkg_check_modules( ncurses++ REQUIRED ncurses++ )
add_executable(odg_control_keyboard_august_26 src/odg_control_keyboard_august_26.cpp)
target_link_libraries(odg_control_keyboard_august_26 ${catkin_LIBRARIES} ncurses)
add_dependencies(odg_control_keyboard_august_26 ${catkin_EXPORTED_TARGETS} odg_control_keyboard_august_26_gencpp)

I also ended up keeping <build_depend>ncurses++</build_depend> and got rid of <run_depend>ncurses++</run_depend>. Afterwards, I stopped getting the error messages, and the program now works the way I want it to.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2014-08-27 16:28:58 -0600

Seen: 1,479 times

Last updated: Aug 28 '14