-
Notifications
You must be signed in to change notification settings - Fork 278
/
Copy pathpid.py
89 lines (75 loc) · 2.98 KB
/
pid.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
'''In this exercise you need to implement the PID controller for joints of robot.
* Task:
1. complete the control function in PIDController with prediction
2. adjust PID parameters for NAO in simulation
* Hints:
1. the motor in simulation can simple modelled by angle(t) = angle(t-1) + speed * dt
2. use self.y to buffer model prediction
'''
# add PYTHONPATH
import os
import sys
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'software_installation'))
import numpy as np
from collections import deque
from spark_agent import SparkAgent, JOINT_CMD_NAMES
class PIDController(object):
'''a discretized PID controller, it controls an array of servos,
e.g. input is an array and output is also an array
'''
def __init__(self, dt, size):
'''
@param dt: step time
@param size: number of control values
@param delay: delay in number of steps
'''
self.dt = dt
self.u = np.zeros(size)
self.e1 = np.zeros(size)
self.e2 = np.zeros(size)
# ADJUST PARAMETERS BELOW
delay = 0
self.Kp = 0
self.Ki = 0
self.Kd = 0
self.y = deque(np.zeros(size), maxlen=delay + 1)
def set_delay(self, delay):
'''
@param delay: delay in number of steps
'''
self.y = deque(self.y, delay + 1)
def control(self, target, sensor):
'''apply PID control
@param target: reference values
@param sensor: current values from sensor
@return control signal
'''
# YOUR CODE HERE
return self.u
class PIDAgent(SparkAgent):
def __init__(self, simspark_ip='localhost',
simspark_port=3100,
teamname='DAInamite',
player_id=0,
sync_mode=True):
super(PIDAgent, self).__init__(simspark_ip, simspark_port, teamname, player_id, sync_mode)
self.joint_names = JOINT_CMD_NAMES.keys()
number_of_joints = len(self.joint_names)
self.joint_controller = PIDController(dt=0.01, size=number_of_joints)
self.target_joints = {k: 0 for k in self.joint_names}
def think(self, perception):
action = super(PIDAgent, self).think(perception)
'''calculate control vector (speeds) from
perception.joint: current joints' positions (dict: joint_id -> position (current))
self.target_joints: target positions (dict: joint_id -> position (target)) '''
joint_angles = np.asarray(
[perception.joint[joint_id] for joint_id in JOINT_CMD_NAMES])
target_angles = np.asarray([self.target_joints.get(joint_id,
perception.joint[joint_id]) for joint_id in JOINT_CMD_NAMES])
u = self.joint_controller.control(target_angles, joint_angles)
action.speed = dict(zip(JOINT_CMD_NAMES.keys(), u)) # dict: joint_id -> speed
return action
if __name__ == '__main__':
agent = PIDAgent()
agent.target_joints['HeadYaw'] = 1.0
agent.run()