Pang, Terry and Mark
Computer
drake-iiwa-driver
FRI
(Fast Research Interface)
via ethernet
IIWA_STATUS
RobotPlanRunner/Manager
IIWA_COMAND
LCM messages at 200Hz
Interesting research code
"Plans"
We'll talk about RobotPlanRunner/Manger today!
Provided by Sammy@TRI
Examples of plans:
server
client
import time
client = PlanManagerZmqClient()
client.make_and_send_plan(...) # sends plan to server.
time.sleep(1.0) # do some work.
client.wait_for_result() # wait for current plan to finish.
import time
client = PlanManagerZmqClient()
client.make_and_send_plan(...) # sends plan to server.
time.sleep(1.0) # do some work.
client.abort() # abort current plan.
send plan and wait for result.
send plan and abort.
class PlanBase {
public:
/* other stuff */
virtual void Step(const State &state, double control_period, double t,
Command *cmd) const = 0;
};
class JointSpaceTrajectoryPlan : public PlanBase {
public:
/* other stuff */
void Step(const State &state, double control_period, double t,
Command *cmd) const override;
};
class TaskSpaceTrajectoryPlan : public PlanBase {
public:
/* other stuff */
void Step(const State &state, double control_period, double t,
Command *cmd) const override;
};
DrakeVisualizer
LCM spy
MockStationSimulation
PlanManager Server
PlanManager Client
NoMoney | HasMoney | Vending | |
---|---|---|---|
Buy | Do nothing. | Start vending, transition to [Vending]. | Wait for vending to finish, then transition to [NoMoney]. |
Cancel | Do nothing. | Return money. | Do nothing. |
Example: vending machine with only one kind of item and two buttons
Buy
Cancel
NoMoney | HasMoney | Vending | |
---|---|---|---|
Buy | Do nothing. | Start vending, transition to [Vending]. | Wait for vending to finish, then transition to [NoMoney]. |
Cancel | Do nothing. | Return money. | Do nothing. |
// vending_machine.h
enum State {kNoMoney, kHasMoney, kVending}
class VendingMachine {
public:
void Buy() {
if (state_ == kNoMoney) {
/* do nothing */
return;
}
if (state_ == kHasMoney) {
state_ = kVending;
VendOneBottle();
return;
}
if (state_ == kVending) {
WaitForVendingToFinish();
state_ = kNoMoney;
return;
}
}
void Cancel() {
/* implementation */
}
private:
State state_;
}
// state_base.h
class StateBase {
public:
virtual void Buy(VendingMachine *vm) = 0;
virtual void Cancel(VendingMachine *vm) = 0;
}
// state_no_money.h
#include "state_base.h"
class StateNoMoney : public StateBase {
public:
void Buy(VendingMachine *vm) override {
/* do nothing */
return;
}
void Cancel(VendingMachine *vm) override {
/* implementation */
}
}
// state_has_money.h
#include "state_base.h"
class StateHasMoney : public StateBase {
public:
void Buy(VendingMachine *vm) override {
vm->ChangeState(StateVending::Instance());
VendOneBottle();
return;
}
void Cancel(VendingMachine *vm) override {
/* implementation */
}
}
// state_vending.h
#include "state_base.h"
class StateVending : public StateBase {
public:
void Buy(VendingMachine *vm) override {
WaitForVendingToFinish();
vm->ChangeState(StateNoMoney::Instance());
return;
}
void Cancel(VendingMachine *vm) override {
/* implementation */
}
}
// vending_machine.h
#include state_base.h
class VendingMachine {
public:
void Buy() {
state_->Buy(this);
}
void Cancel() {
state_->Cancel(this);
}
void ChangeState(StateBase *new_state) {
state_ = new_state;
}
private:
StateBase *state_;
}
Advantage:
Adding new states or changing existing states do not require re-compiling the entire state machine.
IIWA command thread
IIWA_STATUS
IIWA_COMMAND
Plan thread
PLAN_STATUS
Abort thread
Print thread
state_machine->GetCurrentPlan()
state_machine->GetCurrentPlanUpTime()
state_machine->CommandHasError()
state_machine->QueueNewPlan()
state_machine->GetCurrentState()
state_machine->PrintState()
state_machine->AbortPlans()
State machine is shared among the four threads of the server, and locked by a mutex when used.
Plan Status subscription thread
plan_status
main thread
Server
Client
- LCM
- ZMQ Request/Reply
- ZMQ Publish/Subscribe
ROBOT_PLAN
lcm-typed messages are sent through ZMQ instead of LCM.
Maynot be the drake-perfect way to write down a system...
But we don't really know the way drake prefers.
Delay between IIWA_COMMAND messages and their corresponding IIWA_STATUS messages.
Receive IIWA_STATUS
Publish IIWA_COMMAND
callback: decode message, compute command
Delay
Top time consumers
Time spent in output port evaluation (which should call Plan::Step) is only a small fraction of the time in Simulator.
drake systems
multi-threaded