Help with BB8 robot in services_quiz

Hello, i’m trying to get the robot to move in a square, but I cant seem to make it work, as when I call the service, the robot moves only in one direction and the process finishes, ignoring the rest of the movements I have coded it to do. My code is below, if anyone could help me I would appreciate it a lot.

#! /usr/bin/env python

import rospy
from services_quiz.srv import BB8CustomServiceMessage, BB8CustomServiceMessageResponse
from geometry_msgs.msg import Twist
from math import pi

def my_callback(request):
    my_response = BB8CustomServiceMessageResponse()
    sides = request.side
    i = request.repetitions+1
    j = 0
    while j < 4:
        straight(sides)
        rotate()
        j+=1
        
    move.linear.x = 0.0
    pub.publish(move)
    my_response.success = True
    return my_response.success

def straight(sides):
    wait_time = float(sides/10)
    move.linear.x = 0.2
    pub.publish(move)
    rospy.sleep(wait_time)
    move.linear.x = 0.0
    pub.publish(move)

def rotate():
    move.angular.z = 90*2*pi/360
    pub.publish(move)
    rate.sleep()
    move.angular.z = 0
    pub.publish(move)
    rate.sleep()


rospy.init_node('bb8_square') 

pub = rospy.Publisher('/cmd_vel', Twist, queue_size=3)
move = Twist()
my_service = rospy.Service('/move_bb8_in_square_custom', BB8CustomServiceMessage , my_callback) 
rospy.wait_for_service('/move_bb8_in_square_custom')

rate = rospy.Rate(10)

rospy.spin()

Hi @d.zablah, welcome to the community… :innocent:

The use of rate.sleep() in your rotate() function is causing this issue,
rospy.Rate convenience class is used to maintaining a particular rate for a loop and isn’t the most appropriate method for your current application.

I replaced rate.sleep() with rospy.sleep(2) and your bb8 was taking turns just fine.

Happy learning …!!

2 Likes

Thanks for the reply! I have fixed it and now it turns nicely. However, no matter how many repetitions I do it wont go past the first square. Here is the updated code:

#! /usr/bin/env python

import rospy
from services_quiz.srv import BB8CustomServiceMessage, BB8CustomServiceMessageResponse
from geometry_msgs.msg import Twist

def my_callback(request):
    my_response = BB8CustomServiceMessageResponse()
    sides = request.side
    reps = request.repetitions
    moveBB8(reps, sides)
    my_response.success = True
    return my_response.success

def straight(sides):
    wait_time = float(sides/2)
    move.linear.x = 0.3
    pub.publish(move)
    rospy.sleep(wait_time)
    move.linear.x = 0.0
    pub.publish(move)
    rospy.sleep(wait_time)

def rotate():
    move.angular.z = 0.2
    pub.publish(move)
    rospy.sleep(8)
    move.angular.z = 0
    pub.publish(move)
    rospy.sleep(1)

def moveBB8(reps, sides):
    i = -1
    j = 0
    while i < reps:    
        while j < 4:
            straight(sides)
            rotate()
            j+=1
        i+=1

rospy.init_node('bb8_square') 

pub = rospy.Publisher('/cmd_vel', Twist, queue_size=3)
move = Twist()
my_service = rospy.Service('/move_bb8_in_square_custom', BB8CustomServiceMessage , my_callback) 
rospy.wait_for_service('/move_bb8_in_square_custom')

#rate = rospy.Rate(10)

rospy.spin()
1 Like

Hi @d.zablah,

I’d advice you to try to debug this on your own, its a small programming error. If you still can’t figure it out click on the arrow below.

Solution

You forgot to reset the variable j in your while loop after its done executing its first repetition, the correct code should look like this:

def moveBB8(reps, sides):
    i = -1
    j = 0
    while i < reps:    
        while j < 4:
            straight(sides)
            rotate()
            j+=1
        i+=1
        j=0

Happy learning…!!

3 Likes