Unit 3 Topics Quiz: Not subscribed to /odom

Hi,
I’m working on the topics quiz and when submitting the quiz, Gradebot says that I’m not subscribed to /odom. My code runs fine when I run it locally (not through gradebot). I’ve checked the basics as to why that could be, but haven’t found the reason as to what it is. (I also did check the discussion with someone saying the same thing, but my node name is topics_quiz_node unlike theirs). Here is my code for my main file, launch file, setup file and picture workspace tree: (Note: The warning is from unused objects pitch and roll)

import rclpy
# import the ROS2 python libraries
from rclpy.node import Node
# import the Twist module from geometry_msgs interface
from geometry_msgs.msg import Twist
# import the Odometry module from nav_msgs interface
from nav_msgs.msg import Odometry

import numpy as np

from rclpy.qos import ReliabilityPolicy, QoSProfile


class TopicsQuiz(Node):

    def __init__(self):
        # Here you have the class constructor
        # call the class constructor
        super().__init__('topics_quiz_node')
        # create the publisher object
        self.publisher_ = self.create_publisher(Twist, 'cmd_vel', 10)
        # create the subscriber object
        self.subscriber = self.create_subscription(
            Odometry, '/odom', self.odom_callback, QoSProfile(depth=10, reliability=ReliabilityPolicy.RELIABLE))
        # define the timer period for 0.5 seconds
        self.timer_period = 0.5
        # define the variable to save the received info
        self.odom_msg = 0
        # create a Twist message
        self.cmd = Twist()
        self.timer = self.create_timer(self.timer_period, self.motion)

    def euler_from_quaternion(self, quaternion):
        """
        Converts quaternion (w in last place) to euler roll, pitch, yaw
        quaternion = [x, y, z, w]
        Below should be replaced when porting for ROS2 Python tf_conversions is done.
        """
        x = quaternion.x
        y = quaternion.y
        z = quaternion.z
        w = quaternion.w

        sinr_cosp = 2 * (w * x + y * z)
        cosr_cosp = 1 - 2 * (x * x + y * y)
        roll = np.arctan2(sinr_cosp, cosr_cosp)

        sinp = 2 * (w * y - z * x)
        pitch = np.arcsin(sinp)

        siny_cosp = 2 * (w * z + x * y)
        cosy_cosp = 1 - 2 * (y * y + z * z)
        yaw = np.arctan2(siny_cosp, cosy_cosp)

        return roll, pitch, yaw

    def odom_callback(self, msg):
        # print the log info in the terminal
        # self.get_logger().info('I receive odom: "%s"' % str(msg))
        # Save the odom msg
        self.odom_msg = msg

    def motion(self):
        # print the data
        # self.get_logger().info('I receive motion: "%s"' % str(self.odom_msg))

        # Logic of move
        postion_x = self.odom_msg.pose.pose.position.x
        postion_y = self.odom_msg.pose.pose.position.y
        orientation = self.odom_msg.pose.pose.orientation
        roll, pitch, yaw = self.euler_from_quaternion(orientation)

        self.get_logger().info('position X: "%s"' % str(postion_x))
        self.get_logger().info('position Z: "%s"' % str(postion_y))
        self.get_logger().info('yaw: "%s"' % str(yaw))

        if postion_x < 0.8:
            self.cmd.linear.x = 0.2
            self.cmd.angular.z = 0.0
        elif postion_x > 0.75 and yaw < 1.40:
            self.cmd.linear.x = 0.0
            self.cmd.angular.z = 0.25
        elif postion_y < 0.75:
            self.cmd.linear.x = 0.2
            self.cmd.angular.z = 0.0
        else:
            self.cmd.linear.x = 0.0
            self.cmd.angular.z = 0.0

        # Publishing the cmd_vel values to a Topic
        self.publisher_.publish(self.cmd)


def main(args=None):
    # initialize the ROS communication
    rclpy.init(args=args)
    # declare the node constructor
    topics_quiz_node = TopicsQuiz()
    # pause the program execution, waits for a request to kill the node (ctrl+c)
    rclpy.spin(topics_quiz_node)
    # Explicity destroy the node
    topics_quiz_node.destroy_node()
    # shutdown the ROS communication
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Launch file:

from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
    return LaunchDescription([
        Node(
            package='topics_quiz',
            executable='topics_quiz_node',
            output='screen'),
    ])

setup.py:

from setuptools import setup
import os
from glob import glob

package_name = 'topics_quiz'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share', package_name), glob('launch/*.launch.py'))
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='somebody very awesome',
    maintainer_email='user@user.com',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'topics_quiz_node = topics_quiz.topics_quiz_node:main'
        ],
    },
)

Workspace Pic:
image
And this is when the program is run:
image

Hi @couchmec

I’ve never seen this error before, but usually if you delete log, install, build and send in that form to the GradeBot it works.

If not, I can’t think of any other way.

1 Like

Delete each of those directories is what you’re saying correct?

image

I remember when I open a topic about it and several people commented the same thing.

If not works, well, time to call @albertoezquerro

1 Like

Thank you for the help!

It works? If so, don’t forget to mark it as a solution.

1 Like

Not sure this helps but for those also getting the /odom not subscribed error, I saw that not having your node defined as topic_quiz_node in the launch file is a possible problem. I didn’t assign name in the launch file it self like this code shows and it I got full marks on the quiz by defining the executable as topics_node_quiz. Although, this might be helpful to others getting the same issue or those who didn’t define their executable as topics_quiz_node and do not want to mess with the launch file again if their code already runs but is not properly named.

topics_quiz.launch.py**


from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='topics_quiz',
            executable='topics_quiz_node',
            name='topics_quiz_node',
            output='screen'),
    ])
1 Like

Hi @ARodas ,

It is clearly mentioned in the specifications that you must name your node as topics_quiz_node.
Naming your node as topic_quiz_node was basically your fault that you have ignored to notice.

For the next quiz task, please make sure that you have satisfied the specifications by going through your package line-by-line before submitting.

Regards,
Girish

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.