18-642 Project 10
Updated 11/10/2021. Changelog
Learning objectives: finish unit test work from previous project; learn
runtime monitor interface; create a specific monitor in preparation for more
complete monitors in the next project.
We've been telling you all semester that there are some invariants we expect
your turtle to observe, such as not running through walls. This is the first
step in checking and enforcing those invariants. The next project will continue
with more invariant checking.
- Important context: for the final course project at the end of the semester
you will need to do the following. Please plan accordingly.
- Successfully complete all mazes
- Successfully pass unit tests
- Pass monitors that correspond to the high level behavioral requirements
we've been reminding you of all semester
- Update all your design documents to match your final implementation (all
the way from through the V process)
Hints/Helpful Links:
- In this and future projects, $ECE642RTLE_DIR refers to
~/catkin_ws/src/ece642rtle (or corresponding project workspace).
- Please follow the handin naming convention: every filename (before the
file extension) must end in [FamilyName]_[GivenName]_[AndrewID].
- See the Recitation video and slides on Canvas
- Bug fix you might need to make: We had a bug report that the monitor script
was reporting violations that didnt exist and seemed to be triggering on
ROS_INFO lines. After some investigation, it appears that the
run_642_monitors.sh script is matching on regular expressions instead of
literal text which is causing it to match on the info command that affects
some, but not all, students. If this affects you, the corrected code is
- 22: grep -C 5 "\[ WARN\]" $m.output.tmp >>
VIOLATIONS.txt
- 23: m_viol=`grep "\[ WARN\]" $m.output.tmp | wc -l`
Procedure:
- Fix any failing unit tests: Make sure all your unit tests
that you started working on in the previous project execute and pass. Use the
same rules for how many to make and coverage as the previous project. The only
difference is now we expect all the tests to run and pass.
- Study the runtime monitor interface:
- All code is in $ECE642RTLE_DIR/monitors/.
- A runtime monitor is a separate ROS node that eavesdrops on all the ROS
messages sent and received by the turtle. It can keep track of some sort of
stateful turtle behavior by observing the messages.
- Every time a message is sent or received by the turtle, a runtime monitor
receives an "interrupt" with the contents of this message and must
handle the interrupt. Study $ECE642RTLE_DIR/monitors/monitor_interface.h
to see function declarations for these interrupt handlers. Any monitor
you write must implement these functions. (Note that these are more like
simulated interrupts, not literal interrupts on the CPU running the
simulation.)
- A simple logging monitor is implemented in
$ECE642RTLE_DIR/monitors/logging_monitor.cpp. It does not check for
any invariants: it just takes any message it sees and prints out the
information.
- $ECE642RTLE_DIR/monitors/step_monitor.cpp implements a monitor
that checks for the following violation: given a turtle that has gone
between squares A and B, an invariant violation occurs if the Manhattan
Distance between A and B is greater than 1. That is, the turtle shall only move
between adjacent squares. Things to note are the previous Pose stored in
memory, the use of ROS_WARN to display an invariant violation, and the
unimplemented functions that are not needed to be complete for this particular
invariant but are needed for the code to compile.
- Build the monitors using catkin_make ece642rtle_logging_monitor
(or step_monitor).
- In your catkin workspace (proj10_ws or similar), run source
devel/setup.bash and then rosrun ece642rtle ece642rtle_logging_monitor
to run the monitor.
It will display something similar to this: [ERROR]
[1522615024.818666824]: [registerPublisher] Failed to contact master at
[localhost:11311]. Retrying... while the turtle is not
running, which is OK. The node will start running normally when it can connect
with the other nodes.
- In another terminal, run ./build_run_turtle.sh as usual. Then
observe the monitor output in the first terminal.
- Once you get a handle on this workflow, you can run
./run_642_monitors.sh ece642rtle_step_monitor. This takes one or more
monitors as arguments, prints their output to a terminal, and produces a file
called VIOLATIONS.txt that prints out the invariant monitor violations
with five messages of context before and after.
- If the step_monitor does not show any invariant violations, try
changing the code so that an obviously wrong invariant is violated. For
example, change line 31 of the code to treat any movement in the y-
direction to be an invariant violation. Re-build and re-run everything to see
the violation in action!
- Write your own monitor that makes sure that the turtle turns
no more than 90 degrees per simulator time step:
- Use the provided $ECE642RTLE_DIR/monitors/logging_monitor.cpp and
$ECE642RTLE_DIR/monitors/step_monitor.ccp as examples of how to write
the interrupt handlers.
- Name your monitor ANDREWID_turn_monitor.cpp. Make the following addition
(bold) to lines 50-53 of CMakeLists.txt:
# Build the monitors: each target must be in quotes.
# First item is the target name, following items are the source files
# Implicitly all of these are built with monitors/ros_monitor_interface.cpp
set(monitor_TARGETS_SRCS
"ece642rtle_logging_monitor monitors/logging_monitor.cpp"
"ece642rtle_step_monitor monitors/step_monitor.cpp"
"ece642rtle_turn_monitor
monitors/ANDREWID_turn_monitor.cpp"
)
If you include a source file (for example, factored out utility functions), you
can include it in the same line, as ece642rtle_turn_monitor
monitors/ANDREWID_turn_monitor.cpp monitors/ANDREWID_monitor_utils.cpp.
- A more precise way to describe this invariant: If there have been two
subsequent calls to poseInterrupt (because of change in orientation) with
directions A and then B, A and B shall not differ by more than a quarter turn.
For example, EAST to NORTH is acceptable, but EAST to WEST is not.
"Subsequent" in this case applies only to poseInterrupt (so, there
can be calls to other interrupts, such as visitInterrupt or bumpInterrupt,
between the calls to poseInterupt, and they are are still considered
"subsequent" as long as there is no call to poseInterrupt between
them).
- Make sure your monitor code follows good coding practices. A small look-up
table is OK (but not required, if you have another implementation in mind).
- Your code shall use the ROS_WARN function to indicate an
invariant violation. You should use ROS_INFO to print out any relevant
information for your monitor to display. See
$ECE642RTLE_DIR/monitors/step_monitor.ccp as an example.
- Build your code using catkin_make ece642rtle_turn_monitor and run
it by typing source devel/setup.bash from your workspace directory,
and then running ./run_642_monitors.sh ece642rtle_turn_monitor
(recommended), or rosrun ece642rtle ece642rtle_turn_monitor. You can
then use ./build_run_turtle.sh in a new terminal to run your turtle,
and observe the output of the monitor in the first terminal.
- Take note of any invariant violations. Are they due to bugs in your
monitor implementation, or bugs in your turtle implementation? If the former,
fix your monitor implementation until you are confident that it is correct. If
the latter, spend at least an hour (or less, if the invariant is fixed by then)
to fix the invariant violations. In rare cases, ROS timing issues might give
you false positives if messages arrive out of order. If you see these, use the
message timestamps in the log to argue that the violation is a false positive
in the write-up. For this project, you are graded only on the correctness of
your monitor (not the lack of violations), but a some of the next project's
will be for not having invariant violations. You are graded
only on the correctness of your monitor in this project, but in the final
project, you receive credit for running your turtle code without invariant
violations.
- Update your build package to include running this monitor. For later
projects your build package will need to run all the monitors as part of
running the project.
- Answer the following questions in a writeup:
- Your name. (If the writeups are printed out, the file name info is lost,
so put your name and Andrew ID in the document text as well)
- Q1. Are there any unit tests that still don't pass? Which ones, and why?
- Q2. Were there any points that were a specific struggle for unit testing?
(Especially beyond variable scope issues as discussed in the previous project
writeup.)
- Q3. Describe any tricky/subtle points in your invariant monitor
implementation.
- Q4. If you had invariant violations, were they due to issues in your
monitor code, your turtle code, or both? How did you go about fixing them? If
you believe a violation is due to ROS timing issues, make the argument here.
Note that sensistivity to timing issues is inherent in this style of
distributed system architecture, and not a ROS design defect.
- Q5. Include your statechart, including any updates you made for this
project. It should match the transition tests you wrote.
- Q6. Screen shot of maze 1 run showing it reaches goal
- Q7. Screen shot of maze attempt runs 2, 3, 4, 5, and 6 (i.e., screen shots
that includes 5 mazes with how far you got when doing a run; successful
completion is not required)
- Q8. Any problems or things you'd change about this assignment?
Note: By the end of the course, which is coming soon, you will have you
write more invariants (such as "must face the wall segment being checked
for bump" and "does not go through walls") and solve all the
given mazes as well as some new mazes. You will also be expected to have
up-to-date documentation traceability, and your unit tests must pass and
fulfill the coverage criteria. So if you've been slacking on meeting the
invariant requirements, now you have some warning that they are about to be
enforced.
Handin checklist:
Hand in the following:
- Your build file AndrewID_P10.tgz. Make sure all compiler warning flags
are enabled. This shall follow the conventions for previous build files.
- Your AndrewID_build_run_tests.sh script shall run all unit tests.
- Your ./ANDREWID_run.sh k script shall enable and run your monitor
while executing the relevant maze k
- Your writeup, called
p10_writeup_[FamilyName]_[GivenName]_[AndrewID].pdf All the elements of
the writeup shuld be integrated into a single acrobat file, including the peer
review materials. Please don't make the TAs sift through a directory full of
separate image and text files.
Other requirements:
- Use the usual project naming conventions with a prefix of "p10"
for items other than source code.
- The writeup shall be in a single acrobat file for ease of navigation.
- Fonts for all diagrams and text shall be rendered at no smaller than 10
point font. Smaller fonts will require a resubmission
Zip the two files and submit them as P10_[Family
name]_[First name]_[Andrew ID].zip.
The rubric for the project is found here.
Hints:
- You might need to make the following change in some cases:
- Doing catkin_make before catkin_make
ece642rtle_logging_monitor (or step_monitor) has proved to help
students with some build issues.
- We suggest having the system stop after the turtle gets to the goal square
rather than requiring a control-C to stop the process. (Perhaps give it 10
cycles in the goal square and then shut down so it is easy to see that it
actually made it there.) In some cases this helps avoid issues with monitor
messages being lost or scrambled due to messy shut-down scenarios affecting
message buffers.
- There is a sleep statement between launching monitors in the scripts we
give you. In some cases the sleep is too short to finish launching a monitor
(it depends on a lot of conditions such as how fast your virtual machine can
run on your physical machine and might vary from run to run). If you have
problems with monitors not running or situations that work with one monitor but
fail with multiple monitors try lengthening the sleep time in that launching
loop. This will likely be more of an issue in the next project for some
students -- for others everything works fine. It all depends.
- Reminder from project 8: You must not launch additional shells/terminals to
run monitors. You must not assume that TA will spawn another terminal to run
your monitors. You must run the monitors in the background in the same shell.
Entering CTRL+C into the launching command terminal must kill all the
associated processes. There should not be any background processes running. It
is important you understand what a Unix "background process" is and
how to use the "&" character to invoke one (there are many, many
tutorials on the Web on this topic). If you don't use background processes
properly you will encounter problems.
- Some students have found that run_642_monitors.sh script works better if
the monitor killing is separated to into a separate earlier loop instead of
included in the same loop as the output file concatenation
- This seems to be due to flaky behavior that kills all the
monitors instead of just one monitor on the kill_processes command. Shouldn't
happen, but does happen to some students.
- Breaking this into two loops should work for anyone, so it does not break
things if you aren't sure if this is the problem or not. The idea is to kill
all the monitors in one loop, then go back and grab the outputs in a second
loop across all monitors.
- 6/28/2023: released
- 10/20/2023: updated with font size requirement