| Trees | Indices | Help |
|---|
|
|
( concrete )
DESCRIPTION:
-- The Protocol class provides the functionality needed to send messages using the
Dynamixel Protocol as per section 3 of the EX-106 document
RESPONSIBILITIES:
-- detect modules on the bus and generate NodeAdaptors for each one
-- ping modules periodically to ensure that they are still on the Bus??
-- store a queue of pending messages and handle them for during each update
for a given timeslice
-- act as a abstraction layer for basic Bus functionality?
OWNERSHIP:
-- owned by the Cluster
THEORY:
-- The protocol owns a dictionary of the NodeAdaptor of each module
It initially checks for modules by performing a scan for all nodes
that the user states should be on the Bus and for each module
that exists it updates the heartbeat dictionary entry for that node
A heartbeat, is a simple indicator of node existing, holding only a
timestamp and the error received.
Message transmission and reception is based upon the following ideas:
- If asked, Dynamixel servos always send a response
- Dynamixel servos have no Bus arbitration, therefore the response
to a request always follows the request
- There are three types of requests
- Writes that require an acknowledgement
- Reads that require an acknowledgement
- Writes that do not require an acknowledgement
The aformentioned ideas led to the following decisions:
- Messages should be placed in a queue and handled in order of requests
- Message that do not require a response should be sent using the
"SYNC_WRITE" command as per section 3-5-7 pp. 39 in the EX-106 document
and no response should be expected.
- Messages that require a response should be sent and listened for. If a
response is not found, a number of retries should occur to accomodate
for errors
A basic representation of the update() algorithm follows:
get the allowed timeslice
while len queue > 0:
pop message from queue
if message has timed out:
declare message promise as Err
if allowed timeslice is used up:
append message to front of queue and exit
if the message is a broadcast message:
if ping:
warn that broadcast pings are not allowed outside of scan
else:
send message through Bus, and continue to next message
else:
for number of retries remaining in message:
if allowed timeslice is used up:
append message to front of queue and exit
send message through Bus
while have not reached timeout or timeslice is used up:
read in packet
if packet exists:
fulfill message promise, and continue to next message
sleep so that we don't overwork the OS
if no more retries remaining:
declare message promise as Err
CONSTRAINTS:
-- a single write when handled by update must have only a single response
-- it is expected that a Dynamixel Bus has been instantiated as shown in the
Dynamixel Module Examples
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
Inherited from |
|||
|
|||
|
Inherited from |
|||
|
|||
Initialize a Dynamixel Protocol INPUTS: bus -- object -- dynamixel bus object used for basic communication with dynamixel servos nodes -- list -- list of expected dynamixel servo IDs ATTRIBUTES: pnas -- dictionary -- dict of NodeAdaptor objects, used for interfacing with Dynamixel Module heartbeats -- dictionary -- dict of node heartbeats. nid : (timestamp, err) requests -- deque object -- queue of pending requests <<< maybe should just be a list? ping_period -- float -- expected ping period
|
Reset the Protocol object INPUTS: ping_rate -- float -- rate at which to ping nodes OUTPUTS: None THEORY OF OPERATION: scan for nodes, add each node to the pollRing and generate a ProtocolNodeAdaptor |
Build a broadcast ping message and then read for responses, and if
the get_model flag is set, then get model numbers for all existing
nodes
INPUTS:
timeout -- float -- amount of time allowed to scan
retries -- int -- number of times allowed to retry scan
get_model -- bool -- flag determining if node model numbers
should be read to indicate the servo
type
OUTPUTS:
found -- dict -- map from servo IDs that were discovered
to their model numbers, or None if get_model is False
THEORY OF OPERATION:
Assemble packet as per EX-106 section 3-2 pp. 16, using
PING Command as per section 3-5-5 pp. 37 and broadcast ID
Send this packet, then read responses and add to set until
timeout and number of retries.
|
Generate NodeAdaptors for nodes that are not already in pnas INPUTS: nodes -- list -- list of expected nodes THEORY OF OPERATION: Get all node IDs that are in nodes but not in pnas and generate a NodeAdaptors for those nodes
|
Generate NodeAdaptors for given Node ID INPUTS: nid -- int -- ID of node to generate ProtocolNodeAdaptor object for OUTPUTS: pna -- object -- ProtocolNodeAdaptor object for given nid THEORY OF OPERATION: Instantiate ProtocolNodeAdaptor add to pnas dictionary
|
Turn all servos off ... see Bus.off |
Send a memory write command and don't wait for a response INPUTS: addr -- char -- address val -- int -- value pars -- string -- parameters OUTPUTS: msg -- string -- transmitted packet minus SYNC |
Send a memory write command and wait for response, returning it INPUTS: addr -- char -- address val -- int -- value pars -- string -- parameters OUTPUTS: msg -- string -- transmitted packet minus SYNC |
A Protocol level syncronous memory read wrapper around bus.send_cmd_sync
INPUTS:
nid -- int -- node ID
addr -- string hex -- address location to read from
length -- int -- number of bytes to read
retries -- int -- number of times to retry if there exist protocol errors
|
Send a response request by creating an incomplete messsage
and appending it to the queue for handling by update
INPUTS:
nid -- int -- node ID of module
cmd -- int -- command value. ie: CMD_PING, CMD_WRITE_DATA, etc ...
pars -- string -- parameter string
OUTPUTS:
promise -- list -- promise of incomplete message, will be fulfilled upon
successful read
PRECONDITIONS:
None?
POSTCONDITIONS:
None?
THEORY OF OPERATION:
Create an incomplete message for a given request that holds the
packet to be written and has a number of other attributes ( see
Request ) Then append to Protocols queue for later handling
and return a promise that will be fulfilled by a successful read
during Protocol.update()
|
Use pollRing to poll all nodes that haven't been seen for self.ping_rate seconds with ping packets. INPUTS: now -- float -- current time |
The update method handles current incomplete message requests and ensures that
nodes are pinged to check for their existance
INPUTS:
None
OUTPUTS:
num_requests -- int -- length of request queue
PRECONDITIONS:
instantiation of dynamixel.Bus, dynamixel.Protocol
POSTCONDITIONS:
No response occurs
THEORY OF OPERATION:
get the allowed timeslice
while timeslice not done:
if queue empty --> return
pop 1st message on queue
if message has timed out:
fill promise with ProtocolError(timeout)
continue
if message ID is BROADCAST_ID:
if message cmd not CMD_SYNC_WRITE:
bus.send the message
fill promise with None
else:
fill promise with ProtocolError(not CMD_SYNC_WRITE bcast not allowed)
continue
else:
bus.send_cmd_sync the message
store reply in promise
|
Process a single incomplete request If it requires a response -- complete it or time-out; if not, complete with a None reply TODO finish comment |
| Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Thu Jan 4 16:46:17 2018 | http://epydoc.sourceforge.net |