6
6
import math
7
7
from threading import Lock
8
8
9
+ colors = {
10
+ 'red' : '\033 [91m' ,
11
+ 'green' : '\033 [92m' ,
12
+ 'yellow' : '\033 [93m' ,
13
+ 'blue' : '\033 [94m' ,
14
+ 'magenta' : '\033 [95m' ,
15
+ 'cyan' : '\033 [96m' ,
16
+ 'white' : '\033 [97m' ,
17
+ 'reset' : '\033 [0m'
18
+ }
19
+
9
20
class Uart (Node ):
10
21
def __init__ (self ):
11
22
super ().__init__ ('uart_node' )
12
23
13
- self .ROBOT_WIDTH = 0.229
14
- self .ROBOT_LENGTH = 0.550
15
- self .WHEEL_RADIUS = 0.127
16
- self .WHEEL_DIS_FROM_CENTER = 0.229
17
- self .WHEEL_GEOMETRY = 0.550 + 0.229 # Height and width in meters
18
-
19
24
self .pico_pwm = 254
20
- self .max_pwm = 20 / 100 * self .pico_pwm
25
+ self .max_pwm = 20 / 100 * self .pico_pwm / 16
21
26
22
27
self .loop_rate = 0.020 # miliseconds
23
28
self .MotorPWM :[int ,int ,int ,int ]= [0 ,0 ,0 ,0 ]
24
29
30
+ self .matrix_4x3 = np .array ([[15.75 , 0 , - 5.66909078166105 ],
31
+ [0 , 15.75 , 5.66909078166105 ],
32
+ [- 15.75 , 0 , 5.66909078166105 ],
33
+ [0 , - 15.75 ,- 5.66909078166105 ]])
25
34
26
35
self .mutex = Lock ()
27
- self .ser = serial .Serial ('/dev/ttyACM0' , 115200 )
36
+ # self.ser = serial.Serial('/dev/ttyACM0', 115200)
28
37
self .uart_timer = self .create_timer (self .loop_rate ,self .uart_timer_callback )
29
38
self .subscription = self .create_subscription (Twist ,'piRobot/cmd_vel' ,self .twist_callback ,10 )
30
- # self.encoder=self.create_publis++++++++++++++++++++++++++++++++++++++++her(Motor_encoder,'/drive/raw_encoder',10)
39
+ # self.encoder=self.create_publisher(Motor_encoder,'/drive/raw_encoder',10)
40
+ self .get_logger ().info (f"{ colors ['green' ]} Uart Node started " )
31
41
32
42
33
43
def twist_callback (self , msg ):
34
- Vx = msg .linear .x
35
- # Vy = msg.linear.y
36
- Vy = msg .angular .z
37
- # omega = msg.angular.z
38
- omega = msg .linear .y
39
-
40
- self .MotorPWM [0 ] = (Vx - Vy - self .WHEEL_GEOMETRY * omega ) / self .WHEEL_RADIUS
41
-
42
- self .MotorPWM [1 ] = (Vx + Vy + self .WHEEL_GEOMETRY * omega ) / self .WHEEL_RADIUS
43
-
44
- self .MotorPWM [2 ] = (Vx + Vy - self .WHEEL_GEOMETRY * omega ) / self .WHEEL_RADIUS
45
-
46
- self .MotorPWM [3 ] = (Vx - Vy + self .WHEEL_GEOMETRY * omega ) / self .WHEEL_RADIUS
47
-
48
44
49
- # self.MotorPWM[0] = (Vx - Vy - self.WHEEL_DIS_FROM_CENTER * omega) / self.WHEEL_RADIUS # Forward left
50
-
51
- # self.MotorPWM[1] = (Vx + Vy + self.WHEEL_DIS_FROM_CENTER * omega) / self.WHEEL_RADIUS # Forward right
52
-
53
- # self.MotorPWM[2] = (Vx + Vy - self.WHEEL_DIS_FROM_CENTER * omega) / self.WHEEL_RADIUS # backward left
54
-
55
- # self.MotorPWM[3] = (Vx - Vy + self.WHEEL_DIS_FROM_CENTER * omega) / self.WHEEL_RADIUS # backward right
56
-
57
- self .MotorPWM [0 ] = - int (self .MotorPWM [0 ] / 7.87 * self .max_pwm )
58
- self .MotorPWM [1 ] = - int (self .MotorPWM [1 ] / 7.87 * self .max_pwm )
59
- self .MotorPWM [2 ] = int (self .MotorPWM [2 ] / 7.87 * self .max_pwm )
60
- self .MotorPWM [3 ] = int (self .MotorPWM [3 ] / 7.87 * self .max_pwm )
45
+ linear_x = msg .linear .x
46
+ linear_y = msg .linear .y
47
+ angular_z = msg .angular .z
48
+
49
+ # Define a Bot Velocity ~ 3x1 matrix
50
+ matrix_3x1 = np .array ([[linear_x ],
51
+ [linear_y ],
52
+ [angular_z ]])
53
+ # Perform matrix multiplication
54
+ result_matrix = np .dot (self .matrix_4x3 , matrix_3x1 )
55
+
56
+ self .MotorPWM [0 ] = int (result_matrix [0 ] * self .max_pwm )
57
+ self .MotorPWM [1 ] = int (result_matrix [1 ] * self .max_pwm )
58
+ self .MotorPWM [2 ] = int (result_matrix [2 ] * self .max_pwm )
59
+ self .MotorPWM [3 ] = int (result_matrix [3 ] * self .max_pwm )
61
60
62
- self .get_logger ().info ('Motor PWM values: Motor1={}, Motor2={}, Motor3={}, Motor4={}' .format (self .MotorPWM [0 ], self .MotorPWM [1 ], self .MotorPWM [2 ], self .MotorPWM [3 ]))
61
+ self .get_logger ().info ('Motor PWM values: {} Motor1={}, Motor2={}, Motor3={}, Motor4={}' .format (colors [ 'yellow' ], self .MotorPWM [0 ], self .MotorPWM [1 ], self .MotorPWM [2 ], self .MotorPWM [3 ]))
63
62
64
63
def uart_timer_callback (self ):
65
64
66
65
self .mutex .acquire ()
67
66
68
67
try :
69
-
70
68
dataToSend = f"{ self .MotorPWM [0 ]} ,{ self .MotorPWM [1 ]} ,{ self .MotorPWM [2 ]} ,{ self .MotorPWM [3 ]} ,\n " .encode ('utf-8' )
71
69
self .ser .write ('m' .encode ('utf-8' ))
72
70
self .ser .write (dataToSend )
73
71
74
- # response = self.ser.readline().strip()
75
- # self.get_logger().info(f"sent {dataToSend} rec {response}")
76
- # response=0
77
-
78
72
self .ser .write ('e' .encode ('utf-8' ))
79
- # response = self.ser.readline().strip() # read(3) will read 3 bytes
80
- # print(f"revived {response}")
81
-
82
- # todo: publish encoder data here
83
- # encoder_data:[int,int,int]=[int(num) for num in response.split()]
84
73
85
74
finally :
86
75
self .mutex .release ()
@@ -92,4 +81,37 @@ def main(args=None):
92
81
rclpy .shutdown ()
93
82
94
83
if __name__ == '__main__' :
95
- main ()
84
+ main ()
85
+
86
+
87
+ # Archived Lines
88
+
89
+ # Vx = msg.linear.x
90
+ # # Vy = msg.linear.y
91
+ # Vy = msg.angular.z
92
+ # # omega = msg.angular.z
93
+ # omega = msg.linear.y
94
+
95
+ # self.MotorPWM[0] = (Vx - Vy - self.WHEEL_GEOMETRY * omega) / self.WHEEL_RADIUS
96
+ # self.MotorPWM[1] = (Vx + Vy + self.WHEEL_GEOMETRY * omega) / self.WHEEL_RADIUS
97
+ # self.MotorPWM[2] = (Vx + Vy - self.WHEEL_GEOMETRY * omega) / self.WHEEL_RADIUS
98
+ # self.MotorPWM[3] = (Vx - Vy + self.WHEEL_GEOMETRY * omega) / self.WHEEL_RADIUS
99
+
100
+ '''
101
+ self.ROBOT_WIDTH = 0.229
102
+ self.ROBOT_LENGTH = 0.550
103
+ self.WHEEL_RADIUS = 0.127
104
+ self.WHEEL_DIS_FROM_CENTER = 0.229
105
+ self.WHEEL_GEOMETRY = 0.550 + 0.229 # Height and width in meters
106
+ '''
107
+
108
+ # response = self.ser.readline().strip()
109
+ # self.get_logger().info(f"sent {dataToSend} rec {response}")
110
+ # response=0
111
+
112
+
113
+ # response = self.ser.readline().strip() # read(3) will read 3 bytes
114
+ # print(f"revived {response}")
115
+
116
+ # todo: publish encoder data here
117
+ # encoder_data:[int,int,int]=[int(num) for num in response.split()]
0 commit comments