44 uio: packet buffer
55 struct: serlization
66 _TopicInfo: for topic negotiation
7- already provided in rosserial_msgs
7+ already provided in rosserial_msgs
88"""
99
10+ import sys
11+ import logging
1012import machine as m
1113import uio
12- import ustruct as struct
13- from time import sleep , sleep_ms , sleep_us
1414from rosserial_msgs import TopicInfo
15- import sys
16- import os
17- import logging
1815
1916# for now threads are used, will be changed with asyncio in the future
2017if sys .platform == "esp32" :
2926
3027# class to manage publish and subscribe
3128# COULD BE CHANGED AFTERWARDS
32- class NodeHandle ( object ) :
33- def __init__ ( self , serial_id = 2 , baudrate = 115200 , ** kwargs ):
29+ class NodeHandle :
30+ """Initiates connection through rosserial using UART ports."""
3431
32+ def __init__ (self , serial_id = 2 , baudrate = 115200 , ** kwargs ):
3533 """
36- id: used for topics id (negotiation)
37- advertised_topics: manage already negotiated topics
38- subscribing_topics: topics to which will be subscribed are here
39- serial_id: uart id
40- baudrate: baudrate used for serial comm
41- """
42- self .id = 101
34+ id: used for topics id (negotiation)
35+ advertised_topics: manage already negotiated topics
36+ subscribing_topics: topics to which will be subscribed are here
37+ serial_id: uart id
38+ baudrate: baudrate used for serial comm
39+ """
40+ self ._id = 101
4341 self .advertised_topics = dict ()
4442 self .subscribing_topics = dict ()
4543 self .serial_id = serial_id
@@ -69,28 +67,18 @@ def __init__(self, serial_id=2, baudrate=115200, **kwargs):
6967
7068 # method to manage and advertise topic
7169 # before publishing or subscribing
72- def _advertise_topic (self , topic_name , msg , endpoint , buffer_size ):
73-
70+ def _advertise_topic (self , topic_name , _id , msg , endpoint , buffer_size ):
71+ """
72+ topic_name: eg. (Greet)
73+ msg: message object
74+ endpoint: corresponds to TopicInfo.msg typical topic id values
7475 """
75- topic_name: eg. (Greet)
76- msg: message object
77- endpoint: corresponds to TopicInfo.msg typical topic id values
78- """
7976 register = TopicInfo ()
80- register .topic_id = self . id
77+ register .topic_id = _id
8178 register .topic_name = topic_name
8279 register .message_type = msg ._type
8380 register .md5sum = msg ._md5sum
84-
85- self .advertised_topics [topic_name ] = self .id
86-
87- # id are summed by one
88- self .id += 1
89-
90- try :
91- register .buffer_size = buffer_size
92- except Exception as e :
93- logging .info ("No buffer size could be defined for topic negotiation." )
81+ register .buffer_size = buffer_size
9482
9583 # serialization
9684 packet = uio .StringIO ()
@@ -101,17 +89,31 @@ def _advertise_topic(self, topic_name, msg, endpoint, buffer_size):
10189 length = len (packet )
10290
10391 # both checksums
104- crclen = [checksum (le (length ))]
105- crcpack = [checksum (le (endpoint ) + packet )]
92+ crclen = [checksum (_le (length ))]
93+ crcpack = [checksum (_le (endpoint ) + packet )]
10694
10795 # final packet to be sent
108- fpacket = header + le (length ) + crclen + le (endpoint ) + packet + crcpack
96+ fpacket = header + _le (length ) + crclen + _le (endpoint ) + packet + crcpack
10997 self .uart .write (bytearray (fpacket ))
11098
99+ def _advertise_all_topics (self ):
100+ for key , value in self .advertised_topics .items ():
101+ self ._advertise_topic (key , value [0 ], value [1 ], value [2 ], value [3 ])
102+
111103 def publish (self , topic_name , msg , buffer_size = 1024 ):
104+ """publishes messages to topics
105+
106+ Args:
107+ topic_name (string): name of destination topic in ROS network.
108+ msg (ROS message): custom message object generated by ugenpy.
109+ buffer_size (int, optional): maximum size of buffer for message. Defaults to 1024.
110+ """
112111
113112 if topic_name not in self .advertised_topics :
114- self ._advertise_topic (topic_name , msg , 0 , buffer_size )
113+ self .advertised_topics [topic_name ] = [self ._id , msg , 0 , buffer_size ]
114+ # id are summed by one
115+ self ._advertise_topic (topic_name , self ._id , msg , 0 , buffer_size )
116+ self ._id += 1
115117
116118 # same as advertise
117119 packet = uio .StringIO ()
@@ -120,23 +122,33 @@ def publish(self, topic_name, msg, buffer_size=1024):
120122 packet = list (packet .getvalue ().encode ("utf-8" ))
121123 length = len (packet )
122124
123- topic_id = le (self .advertised_topics .get (topic_name ))
124- crclen = [checksum (le (length ))]
125+ topic_id = _le (self .advertised_topics .get (topic_name )[ 0 ] )
126+ crclen = [checksum (_le (length ))]
125127 crcpack = [checksum (topic_id + packet )]
126128
127- fpacket = header + le (length ) + crclen + topic_id + packet + crcpack
129+ fpacket = header + _le (length ) + crclen + topic_id + packet + crcpack
128130 self .uart .write (bytearray (fpacket ))
129131
130- def subscribe (self , topic_name , msgobj , cb , buffer_size = 1024 ):
131- assert cb is not None , "Subscribe callback is not set"
132+ def subscribe (self , topic_name , msg , _cb , buffer_size = 1024 ):
133+ """subscribes to a topic receiving messages and processing them by a callback function
134+
135+ Args:
136+ topic_name (string): name of destiny topic to send messages.
137+ msg (ROS message): custom message object generated by ugenpy.
138+ cb (function): callback function to process incoming messages.
139+ buffer_size (int, optional): maximum size of buffer for message. Defaults to 1024.
140+ """
141+ assert _cb is not None , "Subscribe callback is not set"
132142
133143 # subscribing topic attributes are added
134- self .subscribing_topics [self .id ] = [msgobj , cb ]
144+ self .subscribing_topics [self ._id ] = [msg , _cb ]
135145
136146 # advertised if not already subscribed
137147 if topic_name not in self .advertised_topics :
138- msg = msgobj ()
139- self ._advertise_topic (topic_name , msg , 1 , buffer_size )
148+ self .advertised_topics [topic_name ] = [self ._id , msg , 1 , buffer_size ]
149+ # id are summed by one
150+ self ._advertise_topic (topic_name , self ._id , msg , 1 , buffer_size )
151+ self ._id += 1
140152
141153 def _listen (self ):
142154 while True :
@@ -166,46 +178,47 @@ def _listen(self):
166178 try :
167179 # incoming object msg initialized
168180 msgobj = self .subscribing_topics .get (inid )[0 ]
169- except Exception :
170- logging .info ("TX request was made or got message from not available subscribed topic." )
181+ except (OSError , TypeError , IndexError ):
182+ logging .info (
183+ "TX request was made or got message from"
184+ + "not available subscribed topic."
185+ )
171186 # object sent to callback
172187 callback = self .subscribing_topics .get (inid )[1 ]
173188 fdata = msgobj ()
174189 fdata = fdata .deserialize (msgdata )
175190 callback (fdata )
176191 else :
177192 raise ValueError ("Message plus Topic ID Checksum is wrong!" )
193+ else :
194+ self ._advertise_all_topics ()
178195
179- except Exception as e :
196+ except ( OSError , TypeError , ValueError ) :
180197 logging .info ("No incoming data could be read for subscribes." )
181198
182199
183200# functions to be used in class
184- def word (l , h ):
201+ def word (_l , _h ):
202+ """
203+ Given a low and high bit, converts the number back into a word.
185204 """
186- Given a low and high bit, converts the number back into a word.
187- """
188- return (h << 8 ) + l
205+ return (_h << 8 ) + _l
189206
190207
191208# checksum method, receives array
192209def checksum (arr ):
193- return 255 - ((sum (arr )) % 256 )
194-
210+ """Generates checksum value of message.
195211
196- # little-endian method
197- def le (h ):
198- h &= 0xFFFF
199- return [h & 0xFF , h >> 8 ]
212+ Args:
213+ arr (list): list of hexadecimal values.
200214
215+ Returns:
216+ [int]: returns an value between 0 and 256
217+ """
218+ return 255 - ((sum (arr )) % 256 )
201219
202- # example code
203- if __name__ == "__main__" :
204- from std_msgs import String
205- from uros import NodeHandle
206220
207- msg = String ()
208- msg .data = "HiItsMeMario"
209- node = NodeHandle (2 , 115200 )
210- while True :
211- node .publish ("greet" , msg )
221+ # little-endian method
222+ def _le (_h ):
223+ _h &= 0xFFFF
224+ return [_h & 0xFF , _h >> 8 ]
0 commit comments