openvibers/openvibe.link Commits
Node: speak OpenVibe.Bot's real device protocol (plan T15 follow-up B) (#2)
Changes
@@@ -76,7 +76,8 @@ type Node struct {// configured is set by the first config on a connection; until then only halt runs, so a latch the owner set// while the link was down is applied before any motion.configured bool-- robotIDs []string // from this connection's hello++++ robotIDs []string // the robots this device serves, from the connection's hello}// New builds a Node. Run starts it.@@@ -443,19 +444,18 @@ func (n *Node) pollLatch(ctx context.Context) {// sendEstopState reports the device's latch. Bot reads latched:true as "this device is stopped" and latches the robot// (so the local kill switch shows on the panel and the gate stops sending motion); latched:false is a report only--// and never clears the owner's latch.++// and never clears the owner's latch. robot_id names the robot when the device serves exactly one.func (n *Node) sendEstopState() {if !n.reporting() {return}-- st := n.latch.State()-- // robot_id names the robot only when the device serves exactly one; a bridge for several leaves it out.-- var robot stringn.mu.Lock()++ var robot stringif len(n.robotIDs) == 1 {robot = n.robotIDs[0]}n.mu.Unlock()++ st := n.latch.State()n.send(protocol.EstopState{Latched: st.Stopped(), By: "device", At: time.Now().UTC().Format(time.RFC3339Nano),RobotID: robot, LocalStop: st.Local, Reason: st.RemoteReason})}@@@ -227,8 +227,8 @@ func TestPairConnectAndStatus(t *testing.T) {for _, f := range e.conn.Frames() {if f.Type == protocol.TypeEstopState {sawEstopState = true-- if f.Msg.(protocol.EstopState).Latched {-- t.Fatal("latched on a fresh device")++ if m := f.Msg.(protocol.EstopState); m.Latched || m.RobotID != fakebot.RobotID {++ t.Fatalf("estop_state on a fresh device: %+v", m)}if r := f.Msg.(protocol.EstopState).RobotID; r != fakebot.RobotID {t.Fatalf("estop_state robot_id %q on a one-robot device", r)
@@ -76,7 +76,8 @@ type Node struct {
@@ -76,7 +76,8 @@ type Node struct {
// configured is set by the first config on a connection; until then only halt runs, so a latch the owner set
// configured is set by the first config on a connection; until then only halt runs, so a latch the owner set
// while the link was down is applied before any motion.
// while the link was down is applied before any motion.
configured bool
configured bool
- robotIDs []string // from this connection's hello
+
+ robotIDs []string // the robots this device serves, from the connection's hello
}
}
// New builds a Node. Run starts it.
// New builds a Node. Run starts it.
@@ -443,19 +444,18 @@ func (n *Node) pollLatch(ctx context.Context) {
@@ -443,19 +444,18 @@ func (n *Node) pollLatch(ctx context.Context) {
// sendEstopState reports the device's latch. Bot reads latched:true as "this device is stopped" and latches the robot
// sendEstopState reports the device's latch. Bot reads latched:true as "this device is stopped" and latches the robot
// (so the local kill switch shows on the panel and the gate stops sending motion); latched:false is a report only
// (so the local kill switch shows on the panel and the gate stops sending motion); latched:false is a report only
-// and never clears the owner's latch.
+// and never clears the owner's latch. robot_id names the robot when the device serves exactly one.
func (n *Node) sendEstopState() {
func (n *Node) sendEstopState() {
if !n.reporting() {
if !n.reporting() {
return
return
}
}
- st := n.latch.State()
- // robot_id names the robot only when the device serves exactly one; a bridge for several leaves it out.
- var robot string
n.mu.Lock()
n.mu.Lock()
+ var robot string
if len(n.robotIDs) == 1 {
if len(n.robotIDs) == 1 {
robot = n.robotIDs[0]
robot = n.robotIDs[0]
}
}
n.mu.Unlock()
n.mu.Unlock()
+ st := n.latch.State()
n.send(protocol.EstopState{Latched: st.Stopped(), By: "device", At: time.Now().UTC().Format(time.RFC3339Nano),
n.send(protocol.EstopState{Latched: st.Stopped(), By: "device", At: time.Now().UTC().Format(time.RFC3339Nano),
RobotID: robot, LocalStop: st.Local, Reason: st.RemoteReason})
RobotID: robot, LocalStop: st.Local, Reason: st.RemoteReason})
}
}
@@ -227,8 +227,8 @@ func TestPairConnectAndStatus(t *testing.T) {
@@ -227,8 +227,8 @@ func TestPairConnectAndStatus(t *testing.T) {
for _, f := range e.conn.Frames() {
for _, f := range e.conn.Frames() {
if f.Type == protocol.TypeEstopState {
if f.Type == protocol.TypeEstopState {
sawEstopState = true
sawEstopState = true
- if f.Msg.(protocol.EstopState).Latched {
- t.Fatal("latched on a fresh device")
+ if m := f.Msg.(protocol.EstopState); m.Latched || m.RobotID != fakebot.RobotID {
+ t.Fatalf("estop_state on a fresh device: %+v", m)
}
}
if r := f.Msg.(protocol.EstopState).RobotID; r != fakebot.RobotID {
if r := f.Msg.(protocol.EstopState).RobotID; r != fakebot.RobotID {
t.Fatalf("estop_state robot_id %q on a one-robot device", r)
t.Fatalf("estop_state robot_id %q on a one-robot device", r)