0% found this document useful (0 votes)
12 views15 pages

P04 EFSM Modules

Uploaded by

Isabel Blanco
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views15 pages

P04 EFSM Modules

Uploaded by

Isabel Blanco
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Extended finite state machines:

modularity
• Simulation motor
– Module setup
– Main loop
• EFSM behavior
– init() to setup variables and outputs
– read_inputs() to read primary inputs
– step() to compute next state and variable values
– write_outputs() to write primary outputs
– forward() to update current state and variables
– monitor() to have internal data shown on stdout
– active() to indicate whether EFSM is not at a sink state
Software counter model, 1
begin’ C<B
Counter = {
state = {}, -- state is an object
M = 4, -- counter limit, with default value WAIT
begin COUNT
/ C+ = 0,
begin = nil, -- input signal to start counting B+ = M – 1,
/ C+ = C+1,
B = {}, -- internal boundary limit end = 0
end = 1
C = {}, -- internal counter
c_end = nil, -- output event to signal counting ends C=B
init = function( self, n )
self.state.curr = "WAIT"; self.state.next = "WAIT"
self.M = n or self.M -- if n is nil, then self.M takes default value
self.B.curr = -1; self.B.next = -1; self.C.curr = -1; self.C.next = -1
end -- function init()
,
read_inputs = function( self )
local begin, M = nil, nil
io.write( "> Counter: begin(0/1), M(integer) [whitespace=keep] = " )
--[[ ... --]]
self.begin, self.M = begin, M
end -- function read_inputs()
,
--[[ cont’ed --]]
Software counter model, 2
step = function( self )
if self.begin == nil then
self.state.next = "STOP"; self.state.curr = "STOP“
end -- if
if self.state.curr == "WAIT" then
self.C.next = 0; self.B.next = self.M - 1
if self.begin then self.state.next = "COUNT" end
elseif self.state.curr == "COUNT" then
self.C.next = self.C.curr + 1
if self.C.curr == self.B.curr then self.state.next = "WAIT" end
else -- Stop state or error
begin’ C<B
end -- if chain
end -- function step()
,
WAIT
monitor = function( self ) / C+ = 0, begin COUNT
io.write( "# Counter: state = " ) / C+ = C+1,
B+ = M – 1,
end = 0
--[[ ... --]] end = 1
end -- function monitor()
, C=B
write_outputs = function( self )
io.write( "< Counter: end = " )
if self.c_end then io.write( "1\n" ) else io.write( "0\n" ) end
end -- function write_outputs()
,
--[[ cont’ed --]]
Software counter model, 3
forward = function( self )
self.state.curr = self.state.next
self.B.curr = self.B.next; self.C.curr = self.C.next
if self.state.curr == "WAIT" then self.c_end = true
elseif self.state.curr == "COUNT" then self.c_end = false
else --[[state=="STOP" or error --]] self.c_end = true
end -- if chain
end -- function forward()
,
active = function( self )
return self.state.curr == "WAIT" or self.state.curr == "COUNT"
end -- function active()
} -- Counter

begin’ C<B

WAIT
begin COUNT
/ C+ = 0,
/ C+ = C+1,
B+ = M – 1,
end = 0
end = 1

C=B
Software counter simulator
--SETUP
Counter:init(2)

-- MAIN LOOP
cycle = 0
while Counter:active() do
io.write( string.format( "Cycle = %04i:\n", cycle ) )
Counter:write_outputs()
Counter:monitor()
Counter:read_inputs()
Counter:step()
Counter:forward()
cycle = cycle + 1
end -- while
io.write( "Program exited!\n" )
EFSM execution model
Exercise 4
• Create a timer module
– Timer generates a pulse every M cycles
– Use P04_counter.lua
• Create a module for the odometer
– Use the Lua program from the last exercise
• Deliverables
– Draw of EFSM of the counter with changes to make it
behave as a timer, as described
– List of changes into corresponding code
– Full listing of odometer program
(Code repetitions can be indicated with references)
Exercise 4, cont’d
• For testing
– Create a simulator for the models
– Example with P04_counter.lua
• P04_counter.lua:
local Counter = { --[[ ... --]] }
return Counter
• P04_counter_sim.lua:
local Counter = require “P04_counter”
CoppeliaSim
• Each object can be attached to a Lua script
– Kind of a module without setup & main loop
– Setup and main loop are within CoppeliaSim
• Lots of functions to interact with simulator
– sim.FunctionName
– Scripts can include a setup for the module:
function sysCall_init()
-- setup
end -- sysCall_init()
Robot motion control (1/6)
• NinjUAB / CoppeliaSim case

sim.tubeRead(tubeL1L0handle)

sim.tubeWrite(tubeL0L1handle, stringMessage)

© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2016


Robot motion control (2/6)
• Make it go to a destination point (angle, radius)
– Tell motors speed (PWM signal)
– Which one?
• Characterization of vehicle dynamics
Pairing manipulated with process variables, i.e.
pulse widths with vehicle speed
– How?
• Two step procedure: turning and moving ahead
• Progressive approach

© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2016


Robot motion control (3/6) T‒ B < D

• Characterization INIT/
B+= T TESTING /
– Spinning L+=PWL −
R+=PWR
• Make the robot turn for a while T‒ B ≥ D
• Measure end angle and
NULL/ STOP /
compute rotational speed L+=0, L+=1500,
R+=0 R+=1500

– Moving forward
if self.state.curr == "INIT" then
• Make the robot move self.B.next = sim.getSimulationTime() -- B+ = begin time
ahead for a while self.L.next = PWL -- L+ = pulse width for right motor
self.R.next = PWR -- R+ = pulse width for right motor
• Measure travelled self.state.next = "TESTING"
distance and elseif self.state.curr == "TESTING" then
if (T – self.B.curr) >= 5.0 then -– D = 5.0 seconds
compute linear speed self.state.next = "STOP"
end -- if
elseif self.state.curr == "STOP" then
– State machines self.L.next = 1500; self.R.next = 1500
self.state.next = "NULL"
function sysCall_actuation() elseif self.state.curr == "NULL" then
-- actuating & self.L.next = 0; self.R.next = 0
-- publishing outputs, else -- error
-- i.e. write_outputs() self.state.next = "STOP"
end -- if chain
end
function sysCall_sensing() then
-- sensing (broad ‘sense’), i.e. read_inputs()
-- compute next state and variable values, i.e. step()
-- update current state and variable values, i.e. forward()
end
© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2020
Robot motion control (4/6)
• GO angle distance
– Open-loop mode:
only the vehicle dynamics model is used
T‒ B < D
SPIN/ *
B+=T,
INIT/ WAIT/
<go α r>**
+
L =width***, SPINNING/ *
L+=1500, L+=0, R+=width***, L+=0,
R+=1500 R+=0 D+= |α|/w, R+=0
not A+= α, S+= r
(<go α r>)
T‒ B ≥ D

MOVE/
T‒ B ≥ D MOVING/ * B+=T, *
L+=0, L+=1660,
R+=0 R+=1340,
D +=S/v
T‒ B < D

* Should include responding to commands from L1/user,


including HALT to INITialize the controller, i.e. to return to INIT state
** Input command: I[1] = 1 (code for go), I[2] = α (angle), I[3] = r (radius)
*** Widths depend on turning direction
© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2020
Robot motion control (5/6)
• Moore or Mealy? T‒ B < D
SPIN/ *
B+=T
INIT/ WAIT/
<go α r>**
L+=width***, SPINNING/ *
L+=1500, L+=0, R+=width***, L+=0,
R+=1500 R+=0 D+= |α|/w, R+=0
not A+= α, S+= r
(<go α r>)
T‒ B ≥ D
T‒ B ≥ D
MOVE/
MOVING/ * +
B+=T, *
L+=0, L =1660,
T‒ B < D R+=0 R+=1340,
D +=S/v
T‒ B ≥ D /
L+=1500, R+=1500,
—/ M+=“D GO OK”
L+=1500,
R+=1500 , not
M+=nil (<go α r>) /
L+=0, R+=0, T‒ B < D /
M+= ... **** L+=0, R+=0
* *
WAIT SPINNING MOVING
<go α r>** / T‒ B ≥ D /
B+=T, B+=T,
+ T‒ B < D /
+
L =width***, L =1660,
L+=0, R+=0
R+=width***, R+=1340,
D+= |α|/w, D +=S/v
A+= α, S+= r,
M+=nil

© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2020


Robot motion control (6/6)
• Obstacle detection
– Input read
read_inputs = function( self, D )
-- D is distance in cm from range sensor module, if available
local data = sim.tubeRead(tubeL1L0Handle)
if (data) then
local words = {}
for w in string.gmatch( data, "%d+" ) do
table.insert( words, w )
end
self.I[1] = tonumber( words[1] )
if (self.I[1] == 1) then -- GO
if #words > 1 then self.I[2] = tonumber( words[2] ) - 90 end
if #words > 2 then self.I[3] = tonumber( words[3] ) end
end -- if
else
self.I[1] = 0 -- no command received
end -- if
self.Q = D or self.Q
end, -- function read_inputs()

– Safety distance
– Options
• Stop movement (as HALTed)
• Suspend movement until
– Distance to obstacles > safety distance
– Timeout
© Lluís Ribas Xirgo, Univ. Autònoma de Barcelona, 2020

You might also like