Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into fileconfig-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
cmnrd committed Mar 2, 2022
2 parents b12df01 + f5e54af commit 18df2e7
Show file tree
Hide file tree
Showing 51 changed files with 3,181 additions and 156 deletions.
14 changes: 7 additions & 7 deletions example/C/src/Patterns/lib/SendersAndReceivers.lf
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ reactor SendOnce {
*
* @param offset The starting time.
* @param period The period.
* @param initial The first output.
* @param start The first output.
* @param increment The increment between outputs
*/
reactor SendCount(
offset:time(0),
period:time(1 sec),
initial:int(0),
start:int(0),
increment:int(1)
) {
state count:int(initial);
state count:int(start);
output out:int;
timer t(offset, period);
reaction(t) -> out {=
Expand Down Expand Up @@ -80,7 +80,7 @@ reactor SendOnceAndReceive {
*
* @param offset The time of the first output.
* @param period The period of the outputs.
* @param initial The initial output value.
* @param start The initial output value.
* @param increment The increment between outputs.
*
* @input in The input to report.
Expand All @@ -98,7 +98,7 @@ reactor SendPeriodicallyAndReceive extends SendCount, Receive {
*
* @param offset The time of the first output.
* @param period The period of the outputs.
* @param initial The initial output value.
* @param start The initial output value.
* @param increment The increment between outputs.
*
* @input in The input to report.
Expand All @@ -118,7 +118,7 @@ reactor ReceiveAndSendPeriodically extends Receive, SendCount {
reactor SendPeriodicallyAndReceiveMultiport (
offset:time(0),
period:time(1 sec),
initial:int(0),
start:int(0),
increment:int(1),
width:int(4)
) {
Expand All @@ -127,7 +127,7 @@ reactor SendPeriodicallyAndReceiveMultiport (

timer t(offset, period);

state count:int(initial);
state count:int(start);

reaction(t) -> out {=
SET(out, self->count);
Expand Down
7 changes: 7 additions & 0 deletions example/Python/src/YOLOv5/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
To run the example(s):

First, go to the PyTorch website and follow the instructions to install PyTorch: https://pytorch.org/get-started/locally/

IMPORTANT: If running with NVidia GPU, select the correct CUDA version on the installation page.

Then, install other libraries and compile the LF file:


python3 -m pip install -r requirements.txt
lfc YOLOv5_Webcam.lf # (or lfc YOLOv5_Webcam_Timer.lf)

Expand Down
29 changes: 20 additions & 9 deletions example/Python/src/YOLOv5/YOLOv5_Webcam.lf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
*/
target Python;

preamble {=
BILLION = 1_000_000_000
=}

/**
* Use OpenCV2 to read from the user webcam.
*
Expand All @@ -31,7 +35,7 @@ reactor WebCam(webcam_id(0)) {
while running.is_set():
if ret is True:
# If got a frame, schedule the physical action
frame_action.schedule(0, frame)
frame_action.schedule(0, (get_elapsed_physical_time(), frame))
ret, frame = self.stream.read()
return None
=}
Expand Down Expand Up @@ -93,8 +97,9 @@ reactor DNN {
model.set(self._model)
=}
reaction(frame) -> labels, label_coordinates {=
_, frame_data = frame.value
# Convert the frame into a tuple
fr = [frame.value]
fr = [frame_data]
# Run the model on the frame
results = self._model(fr)
# Extract the labels
Expand All @@ -114,7 +119,8 @@ reactor Plotter(label_deadline(100 msec)) {
input label_coordinates
input model
state _model # Keep the model

state _prev_time(0);

preamble {=
import cv2
=}
Expand Down Expand Up @@ -147,9 +153,10 @@ reactor Plotter(label_deadline(100 msec)) {
sys.stderr.write("Error: Expected all inputs to be present at the same time.\n")
request_stop()

elapsed_time, frame_data = frame.value
# Get how many labels we have
n = len(labels.value)
x_shape, y_shape = frame.value.shape[1], frame.value.shape[0]
x_shape, y_shape = frame_data.shape[1], frame_data.shape[0]
for i in range(n):
row = label_coordinates.value[i]
# If score is less than 0.2 we avoid making a prediction.
Expand All @@ -162,19 +169,23 @@ reactor Plotter(label_deadline(100 msec)) {
bgr = (0, 255, 0) # color of the box
classes = self._model.names # Get the name of label index
label_font = self.cv2.FONT_HERSHEY_SIMPLEX #Font for the label.
self.cv2.rectangle(frame.value, \
self.cv2.rectangle(frame_data, \
(x1, y1), (x2, y2), \
bgr, 2) #Plot the boxes
self.cv2.putText(frame.value,\
self.cv2.putText(frame_data,\
classes[int(labels.value[i])], \
(x1, y1), \
label_font, 0.9, bgr, 2) #Put a label over box.

self.cv2.imshow("frame", frame.value)

fps = int(1 / (elapsed_time / BILLION - self._prev_time / BILLION))
self._prev_time = elapsed_time
self.cv2.putText(frame_data, str(fps), (7, 70),
self.cv2.FONT_HERSHEY_SIMPLEX, 3,
(100, 255, 0), 3, self.cv2.LINE_AA)
self.cv2.imshow("frame", frame_data)
# press 'Q' if you want to exit
if self.cv2.waitKey(1) & 0xFF == ord('q'):
request_stop()

=}

reaction(shutdown) {=
Expand Down
2 changes: 1 addition & 1 deletion example/Python/src/YOLOv5/YOLOv5_Webcam_Timer.lf
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ reactor WebCam {
reaction(camera_tick) -> camera_frame {=
ret, frame = self.stream.read()
if ret is True:
camera_frame.set(frame)
camera_frame.set((get_elapsed_physical_time(), frame))
=}

reaction(shutdown) {=
Expand Down
2 changes: 0 additions & 2 deletions example/Python/src/YOLOv5/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
torch
opencv-python
pandas
tqdm
Expand All @@ -11,7 +10,6 @@ numpy>=1.18.5
Pillow>=7.1.2
PyYAML>=5.3.1
scipy>=1.4.1
torchvision>=0.8.1

# Logging -------------------------------------
tensorboard>=2.4.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Implements a modal LF version of the hierarchical statemachine
* for the behavior tree in presented in this article:
* https://robohub.org/introduction-to-behavior-trees/
*
* Compared to the simple variant this uses modes more extensively, which
* results in the correct behavior.
* Moreover, modeling the sequence in Nominal as modal enables the potential
* use of a history transition that could allow modeling the continuation
* of the task squecnce at the point where it was left when the battery ran out.
*/
target C {
// logging: debug
}

reactor GenericTask(name:string("")) {
output success:bool
output failure:bool

initial mode Running {
// Just for testing
timer work(0, 250msec)
timer finish(1sec, 1sec)

reaction(work) {=
printf("%s\n", self->name);
=}

reaction(finish) -> success, Succeeded, failure, Failed {=
int r = rand() % 6;
if (r == 0) {
SET(failure, true);
SET_MODE(Failed);
} else {
SET(success, true);
SET_MODE(Succeeded);
}
=}
}

mode Succeeded {}
mode Failed {}
}

reactor NominalBehavior {
input BatteryOK:bool

output success:bool
output failure:bool

initial mode MoveToObj {
MoveToObjTask = new GenericTask(name="MoveToObj")

MoveToObjTask.failure -> failure

reaction(MoveToObjTask.success) -> CloseGrip {=
SET_MODE(CloseGrip);
=}
}

mode CloseGrip {
CloseGripTask = new GenericTask(name="CloseGrip")

CloseGripTask.failure -> failure

reaction(CloseGripTask.success) -> MoveHome {=
SET_MODE(MoveHome);
=}
}

mode MoveHome {
MoveHomeTask = new GenericTask(name="MoveHome")

MoveHomeTask.failure -> failure

reaction(MoveHomeTask.success) -> success {=
SET(success, true);
=}
}
}

reactor Robot {
input BatteryOK:bool

output success:bool
output failure:bool

initial mode Nominal {
NominalBehavior = new NominalBehavior()

NominalBehavior.success -> success
NominalBehavior.failure -> failure

reaction(BatteryOK) -> Charging {=
if (!BatteryOK->value) {
SET_MODE(Charging);
printf("Battery empty\n");
}
=}
}

mode Charging {
GoCharge = new GenericTask(name="GoCharge")

GoCharge.failure -> failure

reaction(BatteryOK, GoCharge.success) -> Nominal {=
// Assumes simultaneous presence
if (BatteryOK->value && GoCharge.success->value) {
SET_MODE(Nominal);
printf("Battery charged\n");
}
=}
}
}

main reactor {
timer Battery(1sec, 1sec)
state battery_state:int(1)

robot = new Robot()

reaction(Battery) -> robot.BatteryOK {=
self->battery_state--;
SET(robot.BatteryOK, self->battery_state > 0);
if (self->battery_state <= 0) {
self->battery_state = 5;
}
=}

reaction(robot.success) {=
printf("Total success\n");
request_stop();
=}

reaction(robot.failure) {=
printf("Utter failure\n");
request_stop();
=}

}
Loading

0 comments on commit 18df2e7

Please sign in to comment.