Skip to content

LabCeGoR 2020

Till Hofmann edited this page Mar 24, 2021 · 34 revisions

Lab course at the KBSG in the winter term 2020/2021, see also the KBSG website.

Meetings

  • Nov 11: Intro Meeting (slides)
  • Nov 18: Goal Reasoning Fundamentals (slides) and CLIPS Executive Implmentation (slides)
  • Nov 25: Simulation Setup

Tasks

Task 1

  • Visit all machines (input and output)
  • Start with a single robot
  • Extend to multiple robots
  • Optimize the robot paths

Task 2

Goal: Run a full RCLL production and maximize the score.

Hints:

  • Start with a C0 production. Have another look at the intro slides for a detailed description of the necessary steps.
  • Look at the existing distributed agent to get an idea of the necessary goals and their plans.
  • If you have trouble with a C0 production with all three robots, start with a single robot, then extend to two robots.
  • Continue with C1, C2, C3.
  • Come up with a good overall production strategy to maximize performance. Possibly relevant questions:
    • Which orders should be pursued, and when?
    • How to split up the production of a complex product into sub-goals?
    • How to decide which robot pursues which goal?
  • You should be able to play both as Cyan and Magenta.

Final report

The final report should be a concise description of your approach. In particular, it should describe:

  • The goal tree that you use, including design decisions why you chose this tree
  • The simple (leaf) goals, in comparison to the baseline (e.g., if you split goals differently, why did you do so?)
  • Your changes to the PDDL domain
  • How you coordinate the three robots with the centralized agent
  • Advantages and disadvantages of your approach compared to alternative central agents that you have considered and the baseline (the distributed agent)
  • Main challenges and issues that you have faced

For figures, it is totally fine to take screenshots from the webview, but you may also create your own.

There is no lower limit, it is totally fine if you can describe your approach on one page. A longer report is also good, as long it stays concise and conveys the main ideas properly.

Final Submission

  1. Please push your submission to a branch labcegor$i/final, where $i is your group number
  2. Please send your report to Tarik and Till, CCed all team members

Setup instructions

Setting up your account and VNC

  1. Connect to kirk:

    Your username is the first letter of your first name plus your last name (e.g., thofmann). Your password is your immatriculation number.

  2. Change your password:

    passwd
    
  3. Set a VNC password:

    vncpasswd
    

    VNC passwords are not stored in a safe way. Use a throw-away password!

SSH key setup for your local machine

On your local machine:

  1. Generate an SSH key if you don't have one yet:

    ssh-keygen
    
  2. Copy the key onto kirk:

    ssh-copy-id [email protected]
    

Workspace setup

On the lab machine:

  1. Create an SSH key and add it to your GitHub account

  2. Get the SSH fingerprint from github.com:

    ssh-keyscan github.com >> ~/.ssh/known_hosts
    
  3. Run ansible:

    ansible-pull -i localhost, -U [email protected]:carologistics/ansible.git -C common/simulation-setup --skip-tags packages,services simulation-setup.yml
    

Machine and Group Assignment

  • Group 1: Robin, Lukas: agamemnon
  • Group 2: Chris, Tristan: voyager
  • Group 3: Luis, Anna: pegasus
  • Group 5: Matteo, Emre: defiant

Spare machines: venture, yamato, california, cerritos, enterprise, stargazer, dallas (in order best -> worst performance)

Please coordinate via Slack if you want to use a spare machine!

Running the simulation

Distributed Agent

  1. $ cd $FAWKES_DIR/bin; ./gazsim.bash -r -k --mongodb -n 1 -a (See ./gazsim.bash -h for the meaning of the flags)
  2. In the newly spawned gnome-terminal, you will find the following tabs:
    1. gazebo
    2. general roscore
    3. roscore of robot 1
    4. move base of robot 1
    5. refbox
    6. refbox shell (use this to control the game)
    7. fawkes on robot 1 (check for log output)
    8. fawkes simulation communication
  3. Switch to the refbox shell, then
    1. Press F4 -> CYAN -> Carologistics
    2. Press Space
    3. Press F3 -> PRODUCTION
  4. The robot(s) should start moving now

Central Agent

  1. Run ansible again to fetch the latest changes. You also need to run a clean build:

    ansible-pull -i localhost, -U [email protected]:carologistics/ansible.git -C common/simulation-setup --skip-tags packages,services -e '{ clean_build: true}'  simulation-setup.yml
    

    You only need to do this once.

  2. Run the simulation as above, but with an adapted command:

    ./gazsim.bash -x start -k -r -n 1 --mongodb --central-agent m-central-clips-exec -m gazsim-meta-skiller
    

Troubleshooting

Common issues

  • If you get an error FAWKES_DIR is not set after initial setup, re-start your terminal.

Re-building simulation code

If the simulation is not working without a clear error, try the following:

  1. Run:

    gazebo
    

    If Gazebo does not show up, reach out on Slack, something is broken.

  2. Otherwise, run

    gazebo $GAZEBO_WORLD_PATH
    

    If this works, continue with the next step. If not:

    ccache -C; cd ~/gazebo-rcll; make clean all -j4
    

    If this fails to build because it runs OOM, turn down the number of jobs, e.g., with -j2. Then, try again:

    gazebo $GAZEBO_WORLD_PATH
    

    If this is still not working, reach out on Slack.

  3. Run the full simulation (see above). If this still fails, run:

    cd $FAWKES_DIR; make clean all -j`nproc`
    

    If this is still not working, reach out on Slack.

Skiller simulator

There are two options to simulate the agent:

  • Gazebo simulation with a full physical simulation of the robot.
    • All components that would be used on a real robot are also used in the Gazebo simulation
    • Allows to see what exactly is going on, as the robots actually drive around
    • Also the MPS machines are fully simulated
  • Skiller simulation, where most components are mocked away.
    • Only the CLIPS Executive actually runs
    • Faster and less compute-intensive than Gazebo simulation
    • Skills are simulated by blocking for a fixed amount of time; a skill always succeeds
    • No visualization, as no robot actually moves
    • To see what's going on: Use webview, refbox, log files

To use the skiller simulation, you need to switch the refbox to the latest master branch (and rebuild). Then, run

./gazsim.bash -x start -o -k -r -n 1 --mongodb --central-agent m-central-clips-exec -m m-skill-sim

Note that if you switch back to gazebo, you need to check out common/pre-opcua-refbox-f33 again.

Reproducible Games

Check out the follwing branch in the refbox: tviehmann/game-report-pre-opcua-cxx and build it. In the refbox config you will find several new options:

    # set to true to generate a random field at startup                         
    # disabling randomization requires mongodb to be enabled as the game        
    # parameters are loaded from a mongodb game report in this case             
    random-field: true
    random-machine-setup: true 
    random-orders: true
    random-storage: true
    restore-gamestate:
      enable: false
      phase: PRODUCTION
    # load data from latest game report with a given name
    # leave empty to always load from latest stored report
    load-from-report: ""
    # store game report under a name for later reference
    store-to-report: ""

in order to use those features you need to enable mongodb (by setting the respective config value to true). What then happens is the following: Whenever you start a game a game report is written to a database which contains all information of the game (including stuff that happens during the game such as points, machine status changes etc). You may specify a name for the report for future reference (option store-to-report). You can also use the content of an existing report (load-from-report) in order to load specific data into your current game by setting the respective random-<foo> to false, where <foo> may be one of the following:

  • field: position of machines
  • machine-setup: assignment of rings and downtimes to machines and the assignment of payment to ring colors
  • orders: everything related to orders, quantity requested, delivery window etc
  • storage: assignment of pre-stored workpieces to the storage station (not relevant for this lab as we do not have that feature)

The feature restore-gamestate can be ignored as well. If you leave the report names empty, you will simply load the latest saved game-report (independent from the name it has). If you have multiple game-reports with the same name in your database you will always load the data from the latest one.

You can use the mongo shell to modify your stored game reports, e.g., to whipe all reports:

mongo
> use rcll
> db.game_report.drop()
> exit

CI tests

We have a CI pipeline that builds and tests every push to every branch (see Fawkes Core for a public example). In order to use it, you will need to log in on buildkite.com with your GitHub credentials. After that, you should be able to see the Fawkes Robotino Builds.

To add your own integration tests:

  1. Have a look at rcll-central/cx-simtest.clp. It currently runs a simple test that checks whether you can enter the field. You can extend it with your own test cases.
  2. Run your tests locally by running tests.d/cx-central-simtest.bash. This starts a tmux session and runs the tests.
    • You can attach to the tmux session with tmux attach. Have a look at the manpage for more information on tmux.
    • The log files will occur in tests.out.d/cx-central-simtest

When you push your branch, buildkite will pick up your changes and build the updated branch. Note that

  • buildkite also runs a number of linters and builds the project from scratch. If anything fails before, it will not run the integration test.
  • Integration tests are run as part of the Fawkes build step.
  • The integration tests use the skiller simulation.

Questions

Q: How do I create a goal tree?

A: You can use the functions goal-tree-assert-run-one, goal-tree-assert-run-all, ... to create a goal tree. Here's an example how to use them.


Q: How can I debug the goal reasoner? Where can I see the current goals?

A: Two options:

  1. Look in the web interface at http://localhost:8091/clips-executive.
  2. Look in the debug log in $FAWKES_DIR/bin/debug_11.log.

Q: How can I reduce the spam in the robot11 log?

A: There are 3 main sources of spam: root selection (1), looptime warnings (2) and syncpoint warnings (3) and they can be handled as follows.

(1) This can be changed in the goal reasoner Commit.

(2) This can be changed in the config file Commit

(3) This change is a bit more hacky. You can comment out the the prints in the fawkes code in: fawkes-robotino/fawkes/src/libs/syncpoint/syncpoint.cpp by commenting out both log_warns like this (requies rebuilding of fawkes afterwards):

SyncPoint::handle_default(string component, WakeupType type)
{
    /*
    logger_->log_warn(component.c_str(),
                      "Thread time limit exceeded while waiting for syncpoint '%s'. "
                      "Time limit: %f sec.",
                      get_identifier().c_str(),
                      max_waittime_sec_ + static_cast<float>(max_waittime_nsec_) / 1000000000.f);
    */
    bad_components_.insert(pending_emitters_.begin(), pending_emitters_.end());
    if (!bad_components_.empty()) {
        stringstream message;
        for (set<string>::const_iterator it = bad_components_.begin(); it != bad_components_.end();
             it++) {
            message << " " << *it;
            const auto &last_call =
              std::find_if(emit_calls_.rbegin(), emit_calls_.rend(), [&](const SyncPointCall &call) {
                  return call.get_caller() == *it;
              });
            if (last_call != emit_calls_.rend()) {
                message << " (" << Time().in_sec() - last_call->get_call_time().in_sec() << "s)";
            }
        }
        /*
        logger_->log_warn(component.c_str(), "bad components:%s", message.str().c_str());
        */
    } else if (type == SyncPoint::WAIT_FOR_ALL) {
        throw Exception("SyncPoints: component %s defaulted, "
                        "but there is no pending emitter. This is probably a bug.",
                        component.c_str());
    }
    watchers_wait_for_all_.erase(component);
    watchers_wait_for_one_.erase(component);
}
Clone this wiki locally