Search code examples
python-3.xros

Why error: "must be real number, not RestMode"? How can fix it?


I'm using ROS, and writing some codes to do some tasks, and now I'm facing an error: TypeError: must be real number, not RestMode, for more details, I have code here:

#!/usr/bin/env python
#encoding: utf-8

import rospy
from geometry_msgs.msg import Vector3
from sensor_msgs.msg import Imu
from std_msgs.msg import Float64
import numpy as np
import geometry as geo
import transformation as tf
from IK_solver import IK

class RestMode:
    def __init__(self, bodyDimensions, legDimensions):
#        rospy.Subscriber('spot_keyboard/body_pose',Vector3,self.callback)
        self.bodyLength = bodyDimensions[0]
        self.bodyWidth  = bodyDimensions[1]
        self.bodyHeight = bodyDimensions[2]

        self.l1 = legDimensions[0]
        self.l2 = legDimensions[1]
        self.l3 = legDimensions[2]

#        rospy.Subscriber('spot_imu/base_link_orientation',Imu, self.get_body_pose)
        self.rate = rospy.Rate(10.0) #10Hz
        self.rb = IK(bodyDimensions, legDimensions)

        angles_cmd = [ 'spot_controller/FL1_joint/command',
                       'spot_controller/FL2_joint/command',
                       'spot_controller/FL3_joint/command',
                       'spot_controller/RL1_joint/command',
                       'spot_controller/RL2_joint/command',
                       'spot_controller/RL3_joint/command',
                       'spot_controller/RR1_joint/command',
                       'spot_controller/RR2_joint/command',
                       'spot_controller/RR3_joint/command',
                       'spot_controller/FL1_joint/command',
                       'spot_controller/FL2_joint/command',
                       'spot_controller/FL3_joint/command' ]
        self.joint = []
        for i in range(12):
            self.joint.append(rospy.Publisher(angles_cmd[i], Float64, queue_size=10))

#        self.initial_pose()

    def initial_pose(self,roll=0,pitch=0,yaw=0,dx=0,dy=0,dz=None):
        if dz == None:
            dz = self.bodyHeight

        order = ['FL','RL','RR','FR']
        angles = []

        rospy.loginfo("Start Calculate Angles!")
        for leg in order:
            (q1,q2,q3,ht) = self.rb.calculateAngles(self,roll,pitch,yaw,dx,dy,dz,leg)
            angles.append(q1)
            angles.append(q2)
            angles.append(q3)

        rospy.loginfo("Done! Start publish!")
        for i in range(12):
            self.joint[i].publish(angles[i])

        self.rate.sleep()

if __name__ == '__main__':
    rospy.init_node('rest_mode', anonymous=True)
    body = [0.1908, 0.080, 0.15]
    legs = [0.04, 0.1, 0.094333]
    rest = RestMode(body, legs)
    try:
        while not rospy.is_shutdown():
            rest.initial_pose()

    except rospy.ROSInterruptException:
        pass

When method calculateAngles(self,roll,pitch,yaw,dx,dy,dz,leg) with argument leg in last, it throws: TypeError: must be real number, not RestMode.

But when I change it to first like: calculateAngles(self,leg,roll,pitch,yaw,dx,dy,dz), then error says: TypeError: must be real number, not str with input in another module, but I tested all of the others related module, and they are fine, so I think that must be an issue in codes above!

That error is so strange:

  1. I don't push any str as input
  2. When changing the position of argument leg, it throws a different error.

Solution

  • When calling instance methods, self is an implied parameter, and should never be explicitly passed. When you are using self.rb.calculateAngles(self, ..., that second self is an instance of a RestMode class, which your IK class does not accept...

    Therefore, you want

    (q1,q2,q3,ht) = self.rb.calculateAngles(roll,pitch,yaw,dx,dy,dz,leg)
    

    And change other usages within the IK class as well