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.


Hints/Helpful Links:


Procedure:

  1. 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.
  2. Study the runtime monitor interface:
    1. All code is in $ECE642RTLE_DIR/monitors/.
    2. 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.
    3. 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.)
    4. 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.
    5. $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.
    6. Build the monitors using catkin_make ece642rtle_logging_monitor (or step_monitor).
    7. 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.
    8. In another terminal, run ./build_run_turtle.sh as usual. Then observe the monitor output in the first terminal.
    9. 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.
    10. 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!
  3. Write your own monitor that makes sure that the turtle turns no more than 90 degrees per simulator time step:
    1. 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.
    2. 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.
    3. 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).
    4. 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).
    5. 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.
    6. 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.
    7. 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.
    8. 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.
  4. Answer the following questions in a writeup:

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:

  1. Your build file AndrewID_P10.tgz. Make sure all compiler warning flags are enabled. This shall follow the conventions for previous build files.
  2. 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:

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:

  1. You might need to make the following change in some cases:
  2. 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.
  3. 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.
  4. 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.
  5. 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

Changelog: