No name 'action' in module 'control_msgs'

Hello,

in lection 4.4.1 is a code example for the move_laser.py with

from control_msgs.action import FollowJointTrajectory

but that is not found. I found somewhere other examples for FollowJointTrajectory but they did fail also.

As this is an old course, did anyone also have that issue ?

Regards,
Volker

Hello @vkuehn,

I am investigating the issue and was not able to reproduce your error.

From your terminal, could you please run this command here:

ros2 interface list | grep control_msgs/action

You should see the interface in the list, like so:

control_msgs/action/FollowJointTrajectory
control_msgs/action/GripperCommand
control_msgs/action/JointTrajectory
control_msgs/action/PointHead
control_msgs/action/SingleJointPosition

You can also open a Python Interpreter and see if the import works without error messages.
In a Shell run:

python3

then inside the python interpreter run:

from control_msgs.action import FollowJointTrajectory

I did that and it did not show any errors. Like this:

Could you please post here your results?

Thanks,

Roberto

Hello @rzegers,

to reproduce the error I wanted to start everything again but failed when

ros2 launch my_box_bot_gazebo spawn_robot_ros2_control_velocity.launch.xml

with

file 'spawn_robot_ros2_control_velocity.launch.xml' was not found in the share directory of package 'my_box_bot_gazebo' which is at '/home/user/ros2_ws/install/my_box_bot_gazebo/share/my_box_bot_gazebo'

the file exists in

/home/user/ros2_ws/src/my_box_bot_gazebo/launch/spawn_robot_ros2_control_complete.launch.xm

and build runs through.

interface list looks like this.

    control_msgs/action/FollowJointTrajectory
    control_msgs/action/GripperCommand
    control_msgs/action/JointTrajectory
    control_msgs/action/PointHead
    control_msgs/action/SingleJointPosition

the import on comand line works fine.
VS Code still complains

Any hint ?

Regards,
Volker

Hello Volker,

if you can list the action interface and also import the module using the Python interpreter then we can safely confirm that the package is properly installed. so we can rule out that the package is missing.

Now to the launch file issue:

The fact that the launch file is located inside here the workspace src directory:

~/ros2_ws/src/my_box_bot_gazebo/launch

but not inside the install directory:

~/ros2_ws/install/my_box_bot_gazebo/share/my_box_bot_gazebo

Is an indication that:

1.- Maybe the install statement is missing in your CMakeLists.txt file, so please check that you have this part here inside it:

install(
  DIRECTORY
    launch
    worlds
    models
  DESTINATION
    share/${PROJECT_NAME}/
)

2.- Or maybe you are not sourcing your workspace’s install directory after the build, so please make sure your run

source ~/ros2_ws/install/setup.bash

after you build your package.


EDIT: I just noticed that you have two different launch file names:

1.- The one in your ros2 launch command is:
spawn_robot_ros2_control_velocity.launch.xml

2.- The one on your package’s launch directory is this one:
spawn_robot_ros2_control_complete.launch.xml

So as an additional check please also confirm that the launch file you want to run (spawn_robot_ros2_control_velocity.launch.xml) exists in your package’s launch directory inside your
workspace src directory: ~/ros2_ws/src/my_box_bot_gazebo/launch


Let’s see if this allows you to run that launch file.

Cheers,

Roberto

@rzegers

good spot about the cmake file. As the description and gazebo parts are different projects, the cmake files look like

my_box_bot_description/CMakeLists.txt
install(
  DIRECTORY
    urdf
    rviz
    launch
    meshes
    config
  DESTINATION
    share/${PROJECT_NAME}/
)
my_box_bot_gazebo/CMakeLists.txt
install(
  DIRECTORY
    launch
    worlds
    models
  DESTINATION
    share/${PROJECT_NAME}/
)

install(PROGRAMS
  scripts/move_laser.py
  DESTINATION lib/${PROJECT_NAME}
)

which one do you mean ?

Also I finished lection 4 until the end as it looks like there has been simply missing the launch files.

The rotation commands work fine. Still

ros2 run my_box_bot_gazebo move_laser.py 0.0
Traceback (most recent call last):
  File "/home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py", line 8, in <module>
    from control_msgs.msg import FollowJointTrajectory
ImportError: cannot import name 'FollowJointTrajectory' from 'control_msgs.msg' (/opt/ros/galactic/lib/python3.8/site-packages/control_msgs/msg/__init__.py)

Which CMAke File should contain what ?
Sorry it is really confusing at the moment for me

Regards

Hello @vkuehn,

I think it is confusing because we are discussing two different issues in one thread:

  1. Your issue with the launch file file that you reported on your second message posted here.

  2. Your original issue with the import ImportError: cannot import name 'FollowJointTrajectory' from 'control_msgs.msg'

So just for clarifying : From this sentence it seems to me that you have solved the issue with the launch file that was missing.

Let us focus now on the issue with the import error message that you see.

In your first message you posted that this instruction is giving an error:


from control_msgs.action import FollowJointTrajectory

and now in your last message you have posted an error message like this:


from control_msgs.msg import FollowJointTrajectory

these two a different statements, can you see the difference?

The first one is correct. Please make sure that your file move_laser.py uses the correct import statement which is shown in the course.

Looking forward if this solves the issue,

Roberto

@rzegers

that’s right, not sure where the wrong example came from. Maybe some google result

./my_box_bot_gazebo/scripts/move_laser.py
has now

from control_msgs.action import FollowJointTrajectory

still is not found
image
as no action can’t be resolved.

Unfortunately not solved yet

V

Hello @vkuehn, sad to hear that the import statement is still not working even after confirming that it works using the Python Interpreter and that the import line in your code is now correct.

To continue debugging the issue may I ask you to provide an overview in terms of the files that you have inside ros2_ws/src?

Just execute these two commands and paste the output here in the forum using code blocks:

cd ~/ros2_ws/src

find . | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"

Please paste the complete output here, It might be several lines! Use the icon to maximize the webShells window if necessary for easier copy-pasting the long output.

Then I need your complete version of the move_laser.py file. It it really important that you copy and paste the full file that you have here:

~/ros2_ws/src/my_box_bot_gazebo/scripts/move_laser.py

Copy paste the entire file here, please use code blocks for formatting, please double check that you are copying the correct file!

Next I need you to copy and paste the contents of this CMakeLists.txt file here:
~/ros2_ws/src/my_box_bot_gazebo/CMakeLists.txt

Finally I need the complete error message that you get when you execute:
ros2 run my_box_bot_gazebo move_laser.py 0.0
Important: copy and paste the entire error message, please don’t leave any part out. Too much information is better than too little. Please remember to post as a code block for better readability.

Based on what I can find in the information that you provide we will determine the most useful next course of action.

Regards,

Roberto

@rzegers,

to ease the investigation I would have added the whole src as tar or share the course as rosject, but that is not allowed

Files in src are

.
 |-my_robot_model
 | |-package.xml
 | |-worlds
 | | |-box_bot_empty.world
 | |-launch
 | | |-urdf_visualize_meshes.launch.py
 | | |-spawn_robot_ros2.launch.xml
 | | |-spawn_robot_ros2_control.launch.xml
 | | |-urdf_visualize_meshes_collisions_inertias.launch.py
 | | |-urdf_visualize.launch.py
 | | |-spawn_robot_description.launch.py
 | | |-urdf_visualize_geometric.launch.py
 | | |-start_world.launch.py
 | | |-urdf_visualize_control.launch.py
 | |-.gitignore
 | |-urdf
 | | |-box_bot_physcal_control.urdf
 | | |-box_bot_meshes_collisions_inertias.urdf
 | | |-box_bot_geometric_meshes.urdf
 | | |-box_bot_geometric.urdf
 | | |-box_bot_simple.urdf
 | | |-box_bot.xacro
 | |-.gitattributes
 | |-README.md
 | |-meshes
 | | |-cute_cube.dae
 | | |-sensors
 | | | |-realsense.dae
 | | | |-rplidar.dae
 | | | |-rplidartexture.png
 | | |-lambert3_baseColor.png
 | | |-cute_cube.blend
 | | |-textures
 | | | |-lambert3_baseColor.png
 | |-rviz
 | | |-urdf_vis.rviz
 | |-.git
 | | |-objects
 | | | |-f4
 | | | | |-7e96a06b7c53ff646c75a59220fd305668cb06
 | | | |-17
 | | | | |-5e9866b5e31ef38b46d1d66a38ba2af01656e3
 | | | |-e6
 | | | | |-9de29bb2d1d6434b8b29ae775ad8c2e48c5391
 | | | |-96
 | | | | |-5ebffcb8946808459f2fbdca05650c50e7f9f1
 | | | |-a3
 | | | | |-6c3ea85051a1b05438ab2d414a56c2ba199f36
 | | | |-41
 | | | | |-857dea7c87fe904937d858e5644c00482337fb
 | | | |-1a
 | | | | |-220c54f5306edd20348aec7b4f2727d0b4e758
 | | | |-25
 | | | | |-d8512251aa446ddeeb79e736f16ece2d34f3bf
 | | | |-dc
 | | | | |-ae4731ecc9a93f0b2224b276afd39b0f32eedb
 | | | |-4a
 | | | | |-1dc6139a268ae0fd30b71046804eda6e7fe43b
 | | | |-42
 | | | | |-b3cb026c74e288eea3bfea67485829c9dbdc21
 | | | |-e2
 | | | | |-5a41f5d27259b0f818b6b466983e9c9f362d02
 | | | |-df
 | | | | |-803988c8d66ce49608c305b7c197e4ce0827d6
 | | | |-c2
 | | | | |-fa1206e1c9e8f6dbc56d65cab97b7674b459fb
 | | | |-45
 | | | | |-14db8c00b13e108c028d31941967e938f930e5
 | | | | |-e45cb2ac254be8d18b307932e72b16e3232da6
 | | | |-4e
 | | | | |-accd63b1ff7a5a7832a870996de73bc8f310b6
 | | | |-af
 | | | | |-717cef9414e3bf40cec9b2b46f0ae55cef53a5
 | | | | |-20296fbcc14d0399f6f5c200733892736565b9
 | | | |-88
 | | | | |-b2c8638fc7cdd23edf885f4c97a451d3550f82
 | | | |-b0
 | | | | |-63650e34f3a39d5acde48a4ac33241cb2a43a4
 | | | |-pack
 | | | |-53
 | | | | |-10d27cdd1dcf6ef3ac51649a3ca5a391a6a7d7
 | | | | |-bd63e15ab51b7024a1bba20eb5489647f53219
 | | | |-a6
 | | | | |-968395394d8a3a5dc05960437703ed5323fa50
 | | | |-07
 | | | | |-3dab5927ddf86fc86a9a891f179ee1aa2ca334
 | | | |-7a
 | | | | |-247cd316bd0332f4c1651548a1f158b821e287
 | | | | |-b838f2a994f745207865f3d384fff959a2a7a1
 | | | |-bd
 | | | | |-4a4576eceb22741c892684065cd433755d15ad
 | | | |-80
 | | | | |-35fa1eed62a7bddda488f16bcece6e75627400
 | | | |-c4
 | | | | |-6965865af6ca6de83ce65c4abb8a710b432ff8
 | | | |-0d
 | | | | |-5c9a5a8d05307a3acb83e23f1ef427eb3321f3
 | | | |-ff
 | | | | |-df27c8c67866d0ab180500a67a532e7c7a9dbb
 | | | |-2b
 | | | | |-a0a1059923f74e5cfb8683484c313423c02a2a
 | | | |-9a
 | | | | |-1dc8a21ed2059310336334fe1664c81ebbe639
 | | | |-3a
 | | | | |-176ca12e5d8e92e3022824af336c0b88987ad6
 | | | |-7e
 | | | | |-8d93264541493872ef2618bc1ec125a993d6ab
 | | | |-02
 | | | | |-3fd870195eabb4740686ff14a8f3a7dc402cfb
 | | | |-a5
 | | | | |-b42b80308340c7d85a99bd00ca7f27c837cd69
 | | | |-f5
 | | | | |-e94fae233c3aace9500294b68ccc5b34446444
 | | | |-info
 | | | |-c3
 | | | | |-b07dd88f42ab378369cbc5152694aa3b6e84f1
 | | | |-d3
 | | | | |-947053223194e0d461073b35d494cf4acbf2bb
 | | | |-6a
 | | | | |-33af9cdfc7a2fc335554d6b5f89987d52f8305
 | | | |-c6
 | | | | |-3f2ce42d9117692e704f7467530d7f3b8402a9
 | | | |-cb
 | | | | |-5960a07c564b8c9c5961506f728c774fe0611b
 | | | | |-d5aaa25e7dc7469eba0ad37b1662b8995a80f7
 | | |-refs
 | | | |-tags
 | | | |-heads
 | | | | |-master
 | | | |-remotes
 | | | | |-origin
 | | | | | |-HEAD
 | | |-hooks
 | | | |-update.sample
 | | | |-commit-msg.sample
 | | | |-prepare-commit-msg.sample
 | | | |-pre-rebase.sample
 | | | |-pre-merge-commit.sample
 | | | |-pre-applypatch.sample
 | | | |-applypatch-msg.sample
 | | | |-fsmonitor-watchman.sample
 | | | |-pre-commit.sample
 | | | |-pre-push.sample
 | | | |-post-update.sample
 | | | |-pre-receive.sample
 | | |-config
 | | |-description
 | | |-branches
 | | |-HEAD
 | | |-packed-refs
 | | |-logs
 | | | |-refs
 | | | | |-heads
 | | | | | |-master
 | | | | |-remotes
 | | | | | |-origin
 | | | | | | |-HEAD
 | | | |-HEAD
 | | |-index
 | | |-info
 | | | |-exclude
 | |-CMakeLists.txt
 | |-models
 | | |-box_room
 | | | |-model.sdf
 | | | |-meshes
 | | | | |-box_room.dae
 | | | | |-chambre.png
 | | | |-model.config
 |-my_box_bot_description
 | |-package.xml
 | |-launch
 | | |-urdf_visualize_meshes.launch.py
 | | |-urdf_visualize_rviz_ex_1-1.launch.py
 | | |-urdf_visualize_control_complete.launch.py
 | | |-urdf_visualize_control_velocity.launch.py
 | | |-urdf_visualize_meshes_collisions_inertias.launch.py
 | | |-urdf_visualize.launch.py
 | | |-urdf_visualize_physical.launch.py
 | | |-urdf_visualize_geometric.launch.py
 | | |-urdf_visualize_rviz.launch.py
 | | |-urdf_visualize_control.launch.py
 | |-build
 | | |-.built_by
 | | |-my_box_bot_description
 | | | |-ament_xmllint
 | | | |-ament_cpplint
 | | | |-ament_cmake_package_templates
 | | | | |-templates.cmake
 | | | |-ament_cmake_core
 | | | | |-stamps
 | | | | | |-nameConfig-version.cmake.in.stamp
 | | | | | |-package.xml.stamp
 | | | | | |-package_xml_2_cmake.py.stamp
 | | | | | |-ament_prefix_path.sh.stamp
 | | | | | |-path.sh.stamp
 | | | | | |-nameConfig.cmake.in.stamp
 | | | | | |-templates_2_cmake.py.stamp
 | | | | |-my_box_bot_descriptionConfig.cmake
 | | | | |-package.cmake
 | | | | |-my_box_bot_descriptionConfig-version.cmake
 | | | |-cmake_install.cmake
 | | | |-ament_cmake_environment_hooks
 | | | | |-local_setup.zsh
 | | | | |-path.dsv
 | | | | |-local_setup.dsv
 | | | | |-ament_prefix_path.dsv
 | | | | |-package.dsv
 | | | | |-local_setup.sh
 | | | | |-local_setup.bash
 | | | |-CTestTestfile.cmake
 | | | |-ament_flake8
 | | | |-install_manifest.txt
 | | | |-CMakeFiles
 | | | | |-3.16.3
 | | | | | |-CMakeCXXCompiler.cmake
 | | | | | |-CompilerIdC
 | | | | | | |-a.out
 | | | | | | |-tmp
 | | | | | | |-CMakeCCompilerId.c
 | | | | | |-CompilerIdCXX
 | | | | | | |-CMakeCXXCompilerId.cpp
 | | | | | | |-a.out
 | | | | | | |-tmp
 | | | | | |-CMakeSystem.cmake
 | | | | | |-CMakeCCompiler.cmake
 | | | | | |-CMakeDetermineCompilerABI_CXX.bin
 | | | | | |-CMakeDetermineCompilerABI_C.bin
 | | | | |-my_box_bot_description_uninstall.dir
 | | | | | |-build.make
 | | | | | |-progress.make
 | | | | | |-cmake_clean.cmake
 | | | | | |-DependInfo.cmake
 | | | | |-Makefile2
 | | | | |-CMakeDirectoryInformation.cmake
 | | | | |-progress.marks
 | | | | |-CMakeOutput.log
 | | | | |-cmake.check_cache
 | | | | |-CMakeTmp
 | | | | |-uninstall.dir
 | | | | | |-build.make
 | | | | | |-progress.make
 | | | | | |-cmake_clean.cmake
 | | | | | |-DependInfo.cmake
 | | | | |-TargetDirectories.txt
 | | | | |-CMakeRuleHashes.txt
 | | | | |-Makefile.cmake
 | | | |-ament_cmake_index
 | | | | |-share
 | | | | | |-ament_index
 | | | | | | |-resource_index
 | | | | | | | |-packages
 | | | | | | | | |-my_box_bot_description
 | | | | | | | |-parent_prefix_path
 | | | | | | | | |-my_box_bot_description
 | | | | | | | |-package_run_dependencies
 | | | | | | | | |-my_box_bot_description
 | | | |-ament_copyright
 | | | |-colcon_command_prefix_build.sh.env
 | | | |-CTestCustom.cmake
 | | | |-ament_pep257
 | | | |-CMakeCache.txt
 | | | |-CTestConfiguration.ini
 | | | |-colcon_command_prefix_build.sh
 | | | |-cmake_args.last
 | | | |-ament_cmake_uninstall_target
 | | | | |-ament_cmake_uninstall_target.cmake
 | | | |-colcon_build.rc
 | | | |-ament_uncrustify
 | | | |-ament_cppcheck
 | | | |-ament_lint_cmake
 | | | |-Makefile
 | | |-COLCON_IGNORE
 | |-urdf
 | | |-box_bot_physcal_control.urdf
 | | |-box_bot_control_complete_velocity.urdf
 | | |-box_bot_meshes_collisions_inertias.urdf
 | | |-box_bot_geometric_meshes.urdf
 | | |-box_bot_simple_ex1-1.urdf
 | | |-box_bot_geometric.urdf
 | | |-box_bot_control_complete.urdf
 | | |-box_bot_simple.urdf
 | | |-box_bot_physcal_properties.urdf
 | |-meshes
 | | |-cute_cube.dae
 | | |-sensors
 | | | |-realsense.dae
 | | | |-rplidar.dae
 | | | |-rplidartexture.png
 | | |-lambert3_baseColor.png
 | | |-cute_cube.blend
 | | |-textures
 | | | |-lambert3_baseColor.png
 | |-rviz
 | | |-urdf_vis.rviz
 | |-config
 | | |-controller_position.yaml
 | | |-controller_position_velocity.yaml
 | |-log
 | | |-build_2022-07-18_18-48-28
 | | | |-logger_all.log
 | | | |-my_box_bot_description
 | | | | |-stderr.log
 | | | | |-stdout_stderr.log
 | | | | |-stdout.log
 | | | | |-streams.log
 | | | | |-command.log
 | | | |-events.log
 | | |-latest
 | | |-latest_build
 | | |-COLCON_IGNORE
 | |-install
 | | |-local_setup.zsh
 | | |-my_box_bot_description
 | | | |-share
 | | | | |-my_box_bot_description
 | | | | | |-local_setup.zsh
 | | | | | |-package.xml
 | | | | | |-local_setup.dsv
 | | | | | |-package.ps1
 | | | | | |-launch
 | | | | | | |-urdf_visualize_meshes.launch.py
 | | | | | | |-urdf_visualize_rviz_ex_1-1.launch.py
 | | | | | | |-__pycache__
 | | | | | | | |-urdf_visualize_meshes_collisions_inertias.launch.cpython-38.pyc
 | | | | | | |-urdf_visualize_meshes_collisions_inertias.launch.py
 | | | | | | |-urdf_visualize.launch.py
 | | | | | | |-urdf_visualize_geometric.launch.py
 | | | | | | |-urdf_visualize_rviz.launch.py
 | | | | | |-package.bash
 | | | | | |-hook
 | | | | | | |-cmake_prefix_path.sh
 | | | | | | |-cmake_prefix_path.ps1
 | | | | | | |-cmake_prefix_path.dsv
 | | | | | |-environment
 | | | | | | |-path.dsv
 | | | | | | |-ament_prefix_path.dsv
 | | | | | | |-ament_prefix_path.sh
 | | | | | | |-path.sh
 | | | | | |-package.dsv
 | | | | | |-urdf
 | | | | | | |-box_bot_meshes_collisions_inertias.urdf
 | | | | | | |-box_bot_geometric_meshes.urdf
 | | | | | | |-box_bot_simple_ex1-1.urdf
 | | | | | | |-box_bot_geometric.urdf
 | | | | | | |-box_bot_simple.urdf
 | | | | | |-meshes
 | | | | | | |-cute_cube.dae
 | | | | | | |-sensors
 | | | | | | | |-realsense.dae
 | | | | | | | |-rplidar.dae
 | | | | | | | |-rplidartexture.png
 | | | | | | |-lambert3_baseColor.png
 | | | | | | |-cute_cube.blend
 | | | | | | |-textures
 | | | | | | | |-lambert3_baseColor.png
 | | | | | |-rviz
 | | | | | | |-urdf_vis.rviz
 | | | | | |-cmake
 | | | | | | |-my_box_bot_descriptionConfig.cmake
 | | | | | | |-my_box_bot_descriptionConfig-version.cmake
 | | | | | |-package.sh
 | | | | | |-package.zsh
 | | | | | |-local_setup.sh
 | | | | | |-local_setup.bash
 | | | | |-colcon-core
 | | | | | |-packages
 | | | | | | |-my_box_bot_description
 | | | | |-ament_index
 | | | | | |-resource_index
 | | | | | | |-packages
 | | | | | | | |-my_box_bot_description
 | | | | | | |-parent_prefix_path
 | | | | | | | |-my_box_bot_description
 | | | | | | |-package_run_dependencies
 | | | | | | | |-my_box_bot_description
 | | |-setup.ps1
 | | |-local_setup.ps1
 | | |-_local_setup_util_sh.py
 | | |-setup.sh
 | | |-setup.bash
 | | |-setup.zsh
 | | |-.colcon_install_layout
 | | |-local_setup.sh
 | | |-_local_setup_util_ps1.py
 | | |-COLCON_IGNORE
 | | |-local_setup.bash
 | |-CMakeLists.txt
 |-my_box_bot_gazebo
 | |-package.xml
 | |-worlds
 | | |-box_bot_empty.world
 | |-launch
 | | |-spawn_robot_ros2_physical.launch.xml
 | | |-control.launch.py
 | | |-control_position_velocity.launch.py
 | | |-spawn_robot_ros2_control_velocity.launch.xml
 | | |-spawn_robot_ros2.launch.xml
 | | |-spawn_robot_ros2_control.launch.xml
 | | |-spawn_robot_ros2_control_complete.launch.xml
 | | |-spawn_robot_description.launch.py
 | | |-spawn_robot_II.py
 | | |-start_world.launch.py
 | |-include
 | | |-my_box_bot_gazebo
 | |-src
 | |-scripts
 | | |-move_laser.py
 | |-CMakeLists.txt
 | |-models
 | | |-box_room
 | | | |-model.sdf
 | | | |-meshes
 | | | | |-box_room.dae
 | | | | |-chambre.png
 | | | |-model.config
 |-move_laser.log

ros2 run my_box_bot_gazebo move_laser.py -0.05
or
ros2 run my_box_bot_gazebo move_laser.py 0.0
output

Traceback (most recent call last):
  File "/home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py", line 8, in <module>
    from control_msgs import FollowJointTrajectory
ImportError: cannot import name 'FollowJointTrajectory' from 'control_msgs' (/opt/ros/galactic/lib/python3.8/site-packages/control_msgs/__init__.py)

CMakeLists.txt looks like that.

cmake_minimum_required(VERSION 3.8)
project(my_box_bot_gazebo)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclpy REQUIRED)
find_package(gazebo_ros REQUIRED)
find_package(my_box_bot_description REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  ament_lint_auto_find_test_dependencies()
endif()

install(
  DIRECTORY
    launch
    worlds
    models
  DESTINATION
    share/${PROJECT_NAME}/
)

install(PROGRAMS
  scripts/move_laser.py
  DESTINATION lib/${PROJECT_NAME}
)

ament_package()

I hope you eagle eye the problem.

Cheers,
V

Hi @vkuehn,

the error message that you posted indicates that you have this line of code in your move_laser.py script:

from control_msgs import FollowJointTrajectory

however the correct line for importing the Follow Joint Trajectory action is this one:

from control_msgs.action import FollowJointTrajectory

You are missing the .action after control_msgs

Before we continue please double check that you changed the import line to the correct one as pointed out in my previous reply:

Please I really need you to double check that you have the correct import statement.

I really need you to pay attention to this since you have already two times used wrong import statements and you need to understand that the error message is already pointing you to an error on this import line.

Also, please don’t forget post here the contents of your move_laser.py file as requested:

This will allow me to triple-chek that you have changed the import line indeed.

I am confident that we will get this solved,

Regards,

Roberto

@rzegers

I understand your concerns but realy I just copy pasted it as all the other files.

the complete content

#! /usr/bin/env python3

import sys
import rclpy
from rclpy.duration import Duration
from rclpy.action import ActionClient
from rclpy.node import Node
from control_msgs.action import FollowJointTrajectory
from trajectory_msgs.msg import JointTrajectoryPoint
# ros2 action list -t
# ros2 action info /joint_trajectory_controller/follow_joint_trajectory -t
# ros2 interface show control_msgs/action/FollowJointTrajectory

class SteeringActionClient(Node):

    def __init__(self):
        super().__init__('move_laser_actionclient')
        self._action_client = ActionClient(self, FollowJointTrajectory, '/joint_trajectory_controller/follow_joint_trajectory')

    def send_goal(self, position_value):
        goal_msg = FollowJointTrajectory.Goal()

        # Fill in data for trajectory
        joint_names = ["laser_scan_link_joint"]

        points = []

        point_to_move_to = JointTrajectoryPoint()
        point_to_move_to.time_from_start = Duration(seconds=1, nanoseconds=0).to_msg()
        point_to_move_to.positions = [position_value]

        points.append(point_to_move_to)

        goal_msg.goal_time_tolerance = Duration(seconds=1, nanoseconds=0).to_msg()
        goal_msg.trajectory.joint_names = joint_names
        goal_msg.trajectory.points = points

        self._action_client.wait_for_server()
        self._send_goal_future = self._action_client.send_goal_async(goal_msg, feedback_callback=self.feedback_callback)

        self._send_goal_future.add_done_callback(self.goal_response_callback)
    
    def goal_response_callback(self, future):
        goal_handle = future.result()
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected :(')
            return

        self.get_logger().info('Goal accepted :)')

        self._get_result_future = goal_handle.get_result_async()
        self._get_result_future.add_done_callback(self.get_result_callback)
    
    def get_result_callback(self, future):
        result = future.result().result
        self.get_logger().info('Result: '+str(result))
        rclpy.shutdown()

    def feedback_callback(self, feedback_msg):
        feedback = feedback_msg.feedback

    

def main(args=None):
    
    rclpy.init()

    action_client = SteeringActionClient()

    position_value = float(sys.argv[1])
    future = action_client.send_goal(position_value)

    rclpy.spin(action_client)


if __name__ == '__main__':
    main()

Thanks for keeping up your confidence

And still even after deleting build install log and do a complete rebuild the error looks the same

Regards,
Volker

Hello @vkuehn,

thanks for posting the contents of your move_laser.py script and the full error message, we need that information in every post to be sure about the current state of the python script and to see if the error message has changes or not.

To me the situation at this moment is that the move_laser.py script in your package’s scripts directory has the correct import line BUT the script that is actually being executed has a different import line.

In that case, at the moment, I only can think of one possible cause:

  • The current version of the script has not been installed, and therefore an old version is being called when you run ros2 run my_box_bot_gazebo move_laser.py 0.0

To see the exact content of the file being executed please run this command in a terminal window:

cat /home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py

Then please maximize the shell window (click the icon at the lower right part of the shell window) and copy and paste the output of that command here.

This will show us the file being executed and how the import line in that file looks like.

Looking forward to your reply,
cheers,

Roberto

Hello @rzegers,

as it is to big for my screen here the content

#! /usr/bin/env python3

import sys
import rclpy
from rclpy.duration import Duration
from rclpy.action import ActionClient
from rclpy.node import Node
from control_msgs import FollowJointTrajectory
from trajectory_msgs.msg import JointTrajectoryPoint
# ros2 action list -t
# ros2 action info /joint_trajectory_controller/follow_joint_trajectory -t
# ros2 interface show control_msgs/action/FollowJointTrajectory

class SteeringActionClient(Node):

    def __init__(self):
        super().__init__('move_laser_actionclient')
        self._action_client = ActionClient(self, FollowJointTrajectory, '/joint_trajectory_controller/follow_joint_trajectory')

    def send_goal(self, position_value):
        goal_msg = FollowJointTrajectory.Goal()

        # Fill in data for trajectory
        joint_names = ["laser_scan_link_joint"]

        points = []

        point_to_move_to = JointTrajectoryPoint()
        point_to_move_to.time_from_start = Duration(seconds=1, nanoseconds=0).to_msg()
        point_to_move_to.positions = [position_value]

        points.append(point_to_move_to)

        goal_msg.goal_time_tolerance = Duration(seconds=1, nanoseconds=0).to_msg()
        goal_msg.trajectory.joint_names = joint_names
        goal_msg.trajectory.points = points

        self._action_client.wait_for_server()
        self._send_goal_future = self._action_client.send_goal_async(goal_msg, feedback_callback=self.feedback_callback)

        self._send_goal_future.add_done_callback(self.goal_response_callback)
    
    def goal_response_callback(self, future):
        goal_handle = future.result()
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected :(')
            return

        self.get_logger().info('Goal accepted :)')

        self._get_result_future = goal_handle.get_result_async()
        self._get_result_future.add_done_callback(self.get_result_callback)
    
    def get_result_callback(self, future):
        result = future.result().result
        self.get_logger().info('Result: '+str(result))
        rclpy.shutdown()

    def feedback_callback(self, feedback_msg):
        feedback = feedback_msg.feedback

    

def main(args=None):
    
    rclpy.init()

    action_client = SteeringActionClient()

    position_value = float(sys.argv[1])
    future = action_client.send_goal(position_value)

    rclpy.spin(action_client)


if __name__ == '__main__':
    main()

And looks like you are right. Odd I could swear I have deleted multiple times the install and build paths.
How to fix that ?

Regards,
Volker

Hi @vkuehn,

thanks for posting the contents of

/home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py

which is the installed file as you can see the path is

/home/user/ros2_ws/install/my_box_bot_gazebo/

and not

/home/user/ros2_ws/src/my_box_bot_gazebo/

This explains why, even when you changed the python file inside you package you will still getting the same error.

Now the next step is to clean the build, install and log directories inside your ros2_ws.
To do so please execute:

cd ~/ros2_ws
rm -rf build install log
ls

Execute ls to confirm the operation. Please post the output of ls here.
Next, execute the command that we used to display the content of the file that is causing trouble:

cat /home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py

This should output an error message, please paste the error message here just to confirm that this step is ok before we proceed.

Cheers,

Roberto

Hi @rzegers,

ls shows just the src folder now.

Therefore cat shows

at: /home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py: No such file or directory

Cheers,
Volker

Hi @vkuehn,

that is very good, now we have a clean state from which to start.

next step is to compile and source your workspace again:

cd ~ros2_ws
colcon build
source install/setup.bash

Next let’s see if the python file exists inside /home/user/ros2_ws/install/ to do so please run this command again:

cat /home/user/ros2_ws/install/my_box_bot_gazebo/lib/my_box_bot_gazebo/move_laser.py

It should show the the source code of move_laser.py, please post it here so we can both confirm that this version now has the correct import statement line.

Cheers,

Roberto

yehaa…

#! /usr/bin/env python3

import sys
import rclpy
from rclpy.duration import Duration
from rclpy.action import ActionClient
from rclpy.node import Node
from control_msgs.action import FollowJointTrajectory
from trajectory_msgs.msg import JointTrajectoryPoint
# ros2 action list -t
# ros2 action info /joint_trajectory_controller/follow_joint_trajectory -t
# ros2 interface show control_msgs/action/FollowJointTrajectory

class SteeringActionClient(Node):

    def __init__(self):
        super().__init__('move_laser_actionclient')
        self._action_client = ActionClient(self, FollowJointTrajectory, '/joint_trajectory_controller/follow_joint_trajectory')

    def send_goal(self, position_value):
        goal_msg = FollowJointTrajectory.Goal()

        # Fill in data for trajectory
        joint_names = ["laser_scan_link_joint"]

        points = []

        point_to_move_to = JointTrajectoryPoint()
        point_to_move_to.time_from_start = Duration(seconds=1, nanoseconds=0).to_msg()
        point_to_move_to.positions = [position_value]

        points.append(point_to_move_to)

        goal_msg.goal_time_tolerance = Duration(seconds=1, nanoseconds=0).to_msg()
        goal_msg.trajectory.joint_names = joint_names
        goal_msg.trajectory.points = points

        self._action_client.wait_for_server()
        self._send_goal_future = self._action_client.send_goal_async(goal_msg, feedback_callback=self.feedback_callback)

        self._send_goal_future.add_done_callback(self.goal_response_callback)
    
    def goal_response_callback(self, future):
        goal_handle = future.result()
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected :(')
            return

        self.get_logger().info('Goal accepted :)')

        self._get_result_future = goal_handle.get_result_async()
        self._get_result_future.add_done_callback(self.get_result_callback)
    
    def get_result_callback(self, future):
        result = future.result().result
        self.get_logger().info('Result: '+str(result))
        rclpy.shutdown()

    def feedback_callback(self, feedback_msg):
        feedback = feedback_msg.feedback

    

def main(args=None):
    
    rclpy.init()

    action_client = SteeringActionClient()

    position_value = float(sys.argv[1])
    future = action_client.send_goal(position_value)

    rclpy.spin(action_client)


if __name__ == '__main__':
    main()

Very odd I would have thought I have done all this. However it looks ok right ?

Cheers,
Volker

Hi @vkuehn,

yes it looks correct now. This is the line we care about and it looks just fine:

from control_msgs.action import FollowJointTrajectory

Last step is to execute it, just run the ros2 run command:

ros2 run my_box_bot_gazebo move_laser.py 0.0

Fingers crossed!

Cheers,

Roberto

Hi @rzegers,

nothing happens and still the issue is that the action package can’t be resolved

image

:frowning: to sad. Any Idea ?

Cheers,
Volker

hi @vkuehn,

you can ignore that red underline that is shown in the code editor for now. Please execute the ros2 run command and see if there is an error message or if it runs.

Cheers,

Roberto