简体   繁体   中英

TypeError: unsupported operand type(s) for +=: 'float' and 'function'

I'm just trying to simulate a simple path planning problem using an artificial potential field (APF). To do so, I have a Point class each instance of which represents the location of an agent. A bunch of functions to move the agent's location, to find its distance to some other points, and to compute an APF corresponding to that are implemented. An Obstacle class is also defined each instance of which is simply a point in addition to the obstacle's radius.

import autograd.numpy as np
from autograd import grad
import math

class Point(object):

    def __init__(self,x,y):
        self.X = x
        self.Y = y

    def distance(self, goal):
        dx = self.X - goal.X
        dy = self.Y - goal.Y
        return math.hypot(dx, dy)

    def move(self, value):
        self.X += value
        self.Y += value

    def APF(self, goal, k, obstacles):
        num = self.distance(goal)**2
        temp = self.distance(goal)**(2*k)
        for item in obstacles:
            temp = temp + (self.distance(item.point)**2 - item.radius**2)
        den = temp**(1/k)
        return num/den

class Obstacle(object):
    def __init__(self, point, radius):
        self.point = point
        self.radius = radius

To test the code above, the following main snippet is taken into account. In particular, it is supposed to iteratively compute the gradient of the APF and to add the result to the agent's location (say, moving it) until the gradient vanishes.

if __name__== "__main__" :
    start = Point(0.0, 0.0)
    goal = Point(15.0, 5.0)

    p1 = Point(2.0, 2.0)
    p2 = Point(3.0, 3.0)
    p3 = Point(4.0, 4.0)
    p4 = Point(5.0, 5.0)
    obs1 = Obstacle(p1, 1.0)
    obs2 = Obstacle(p2, 2.0)
    obs3 = Obstacle(p3, 3.0)
    obs4 = Obstacle(p4, 4.0)

    obstacles = [obs1, obs2, obs3, obs4]
    trajectory = [start]

    k = 7.0 
    temp = start

    while grad(temp.APF(goal, k, obstacles)) != 0.0:
        next = temp.move(grad(temp.APF(goal, k, obstacles)))
        trajctory.append(next)
        temp = next

However, I've encountered the following error:

Traceback (most recent call last):
  File "test_APF.py", line 53, in <module>
    next = temp.move(grad(temp.APF(goal, k, obstacles)))
  File "test_APF.py", line 17, in move
    self.X += value
TypeError: unsupported operand type(s) for +=: 'float' and 'function'

To me APF returns numbers so grad should be okay with it. Then, move will also receive numbers as it argument. Can you please help me spotting the issue?

According to the Autograd readme , autograd.grad() returns a function.

>>> grad_tanh = grad(tanh)       # Obtain its gradient function
>>> grad_tanh(1.0)               # Evaluate the gradient at x = 1.0

You're passing the function, not its return value, to your .move() function.

import autograd.numpy as np
from autograd import grad
import math



def APF(k,start,goal, obstacles):
    dist = math.hypot(start[0] - goal[0], start[1] - goal[1])
    num = dist**2
    temp = dist**(2*k)
    for item in obstacles:
        temp = temp + (dist ** 2 - item.radius ** 2)
    den = temp ** (1 / k)
    return num / den

class Point(object):

    def __init__(self,x,y):
        self.X = x
        self.Y = y

    def distance(self, goal):
        dx = self.X - goal.X
        dy = self.Y - goal.Y
        return math.hypot(dx, dy)

    def move(self, value):
        self.X += value
        self.Y += value



class Obstacle(object):
    def __init__(self, point, radius):
        self.point = point
        self.radius = radius

if __name__== "__main__" :
    start = (0.0, 0.0)
    goal = (15.0, 5.0)

    p1 = Point(2.0, 2.0)
    p2 = Point(3.0, 3.0)
    p3 = Point(4.0, 4.0)
    p4 = Point(5.0, 5.0)
    obs1 = Obstacle(p1, 1.0)
    obs2 = Obstacle(p2, 2.0)
    obs3 = Obstacle(p3, 3.0)
    obs4 = Obstacle(p4, 4.0)

    obstacles = [obs1, obs2, obs3, obs4]
    trajectory = [start]

    k = 7.0
    temp = start


    print(grad(APF)(k,start,goal, obstacles))

        # next = temp.move(grad(temp.APF(goal, k, obstacles)))
        # trajctory.append(next)
        # temp = next

You have to create two classes to handle this.. See my reference class for info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM