theRAPTLab / gsgo

GEM-STEP Foundation repo migrated from GitLab June 2023
1 stars 1 forks source link

Mini-Rounds - [merged] #555

Closed benloh closed 1 year ago

benloh commented 3 years ago

Merges dev-bl/mini-round-phases -> dev

Branch: dev-bl/mini-round-phases

This adds support for defining and running mini-rounds of simulation runs. It was designed primarily for the Moths project.

To Test

  1. Make sure Pozyx is up and running.

  2. git fetch && git checkout dev-bl/mini-round-phases

  3. npm run bootstrap && npm run gem

  4. Go to http://localhost/app/main?model=moths-sandbox

  5. A "Round 1" message should appear. Click OK.

  6. Click "PREP COSTUMES" -- Use a Pozyx tag to inhabit a Moth. (Predators are AI controlled in this version of moths-sandbox).

  7. Click "START ROUND"

  8. The round timer for round 1 is set to 10 seconds. It should start going down as soon as you click "START ROUND"

  9. The round should be long enough for the Predator to find and eat one Moth.

  10. When the round stops, a end of round message appears. Click OK.

  11. Note the pozyx tags stop updating.

  12. Click "PREP NEXT ROUND"

  13. A "Round 2" message appears. And the pozyx tags resume updating.

  14. If your moth survived the first round, the tag should still be connected to the moth.

  15. Any moths that survived should spawn a new moth within two clicks of their current color.

  16. Dead moths should be removed. If your pozyx tag had inhabited a moth that was eaten, you should be released from that moth and free to pick up another moth.

  17. Click "PREP COSTUMES" again to pick up new moths.

  18. Click "START ROUND" to start the second round.

  19. The line graphs on Moths should continue plotting (and not start plotting again at 0 like they used to).

  20. The round will end if...

    • the predator eats all of the moths, the round will end. The end round message will include a message about all moths being eaten.
    • or, you click "STOP ROUNDS"
    • or, the timer runs out.
  21. After the end of the round, the only button available is "RESET STAGE" -- the project is defined such that it will only run through two rounds and then end. You can customize this so that after the pre-defined rounds have completed, the system will go back to round 1 again.


Overview

Mini-Rounds support was built for the Moths activity. It involves MANY features scattered across the system.


Rounds

You can define rounds in the project script file, e.g. aquatic.js.

Options

Rounds have two options:

allowResetStage option

(Not currently implemented)

Default: 'true'

If set to 'true' the "RESET STAGE" button will be available at any time. If set to 'false' the "RESET STAGE" button will only be shown during PRERUN.

noloop option

Default: false

If set to true, rounds will stop after all predefined rounds have been run. If set to false or not defined, rounds will loop, going back to round 1 once you've reached the last round.

Rounds Definition

You can define as many rounds as you want.

If you don't define any rounds, the system will by default let you run and endless round, and allow you to re-run the round after stopping.

Timer

time defines the length of the round, in seconds. Each round can have a different timer setting. If time is not set, the timer will not be used and the round will continue until someone presses "STOP ROUND".

Rounds Messages: intro and outtro

Each round can have an optional intro and outtro message. intro is shown at PRERUN. outtro is shown at STOP.

Rounds Scripts: initScript and endScript

Each round can have a separate initScript and endScript.

initScript runs when the user presses "PREP NEXT ROUND". endScript runs when the round is stopped either by the timer, script command, or if the user presses the "STOP ROUND" button.

Scripts are run in the context of the GlobalAgent. By default GlobalAgent has the Population feature enabled. Any other features need to be added manually. They can be added in the initScript.

You can use the initScript, for instance, to remove dead Moths and spawn new Moths from any remaining Moths.

Example

export const MODEL = {
  label: 'Moths',
  rounds: {
    options: {
      allowResetStage: false,
      noloop: true // stop after last round
    },
    roundDefs: [
      {
        time: 10,
        intro: 'First generation',
        initScript: `dbgOut 'Round1!'
// demo: add AgentWidgets so we can stuff more messages into the intro text
useFeature AgentWidgets
featCall AgentWidgets showMessage '1. Press "PREP COSTUMES" to put on costumes.'
featCall AgentWidgets showMessage '2. Press "START ROUND" when ready!'
`,
        outtro: 'What happened?',
        endScript: `dbgOut 'END Round1!'`
      },
      {
        time: 60,
        intro: 'Spawned and mutated!',
        initScript: `dbgOut 'Round2'
// Release Cursors from Dead Moths
featCall Population releaseInertAgents
// Remove Dead Moths
featCall Population hideInertAgents
// Spawn New Moths
featCall Population agentsReproduce Moth [[
  prop x addRnd -64 64
  prop y addRnd -64 64
  featProp Costume colorScaleIndex addRnd -2 2 true
  // featCall Costume randomizeColorHSV 1 1 1
]]
featCall Population agentsForEach TreeFoliage [[
  featProp Costume colorValue sub 0.1
]]
`,
        outtro: 'What happened to spawn?',
        endScript: `dbgOut 'END Round2!'`
      }
    ]
  },
}

Costume Feature

Color Scale

Agent colors can be assigned to a predefined series of colors in a graded scale. To use this feature, you need to:

  1. Define the colorscale: intHSVColorScale
  2. Set a Costume property: colorScaleIndex

initHSVColorScale method

Syntax

featCall Costume initHSVColorScale <baseHue> <baseSaturation> <baseValue> <type> <count>

where

Example

featCall Costume initHSVColorScale 0 0 1 'value' 11

This will create a scale of 11 gray values. 0 0 1 is white, since there is no saturation and value is maxed.

colorScaleIndex property

To set the agent to a color, just set the colorScaleIndex property. The corresponding color will be automatically applied during the VIS_UPDATE cycle.

colorScaleIndex is a GVarNumber, so you can use GVar math.

We implemented this as a featProperty so that you can easily do math with it.

For example, this will set the agent to the 9th color in the scale.

featProp Costume colorScaleIndex setTo 9

For example, this will change the colorScaleIndex value by a random value up to +/-2.

featProp Costume colorScaleIndex addRnd -2 2 true

GVarNumber

Random Number Routines

In order to support integer random numbers, we've introduced a new flag that can be used with the GVarNumber random number routines. Passing true will force the random number to be an integer.

e.g. colorScaleIndex addRnd -2 2 might result in adding 1.8593234 e.g. colorScaleIndex addRnd -2 2 true might result in rounding up 1.8593234 to 2.


Population Feature

agentsForEach method

agentsForEach allows you to iterate over all agents of a given blueprint. This is primarily intended for use in initScript and endScript.

NOTE: agentsForEach only operates on non-Inert agents. It skips over inert agents.

Syntax

featCall Population agentsForEach <blueprint> [[ <script> ]]

Where <blueprint> is a blueprint name, e.g. "Moth", and <script> is the GEMSCRIPT you want to run on each agent.

Example

This will darken all the non-inert TreeFoliage objects as part of an initScript.

featCall Population agentsForEach TreeFoliage [[
  featProp Costume colorValue sub 0.1
]]

getActiveAgentsCount method

Returns the number of active (non-inert) agents of a particular blueprint type.

Syntax

featCall Population getActiveAgentsCount <blueprint>

where <blueprint> is the name of a blueprint, e.g. "Moth".

Since this returns a value, most likely you'd use it in an ifExpr. See the example below.

Example

// Stop sim if no more agents
ifExpr {{ Moth.callFeatMethod('Population', 'getActiveAgentsCount', 'Moth') < 1 }} [[
  featCall Predator.Timer stopRound
]]

Agents


AgentWidgets Feature

showMessage method

showMessage will display a message in a popup modal dialog window with an "OK" button.

If you send multiple messages before the user has clicked OK, each subsequent message will appear on a separate line in the dialog window.

NOTE: No formatting is allowed in the message. If you want separate lines, send a second message.

Syntax

featCall AgentWidgets showMessage '<string>'

where <string> is your message.

Example

featCall AgentWidgets showMessage 'Hello World'


Timer Feature

stopRound method

You can stop a running round via script using the stopRound method.

Syntax

featCall Timer stopRound

Example

This will stop a round after all Moths are gone:

useFeature Timer
// Stop sim if no more agents
ifExpr {{ Moth.callFeatMethod('Population', 'getActiveAgentsCount', 'Moth') < 1 }} [[
  featCall Predator.Timer stopRound
]]

Under the Hood (Developer Notes)


Questions

  1. Should "RESET STAGE" still be visible all the time? Do we want to hide it once PREP COSTUMES or START ROUND has been pressed?

To Do

benloh commented 3 years ago

Spend 1.25h document and write merge request.

benloh commented 3 years ago

added 1h 15m of time spent

benloh commented 3 years ago

In GitLab by @jdanish on Jun 25, 2021, 06:58

Note: I believe the first round is set to 3 seconds - not a big deal but just saying it here so no one else things it is a bug.

benloh commented 3 years ago

In GitLab by @SimeonOA on Jun 25, 2021, 07:38

I think steps should include reminder to update mqtt connect with specific local MQTT server info every time a new branch is checked out.

benloh commented 3 years ago

In GitLab by @SimeonOA on Jun 25, 2021, 11:00

@benloh

Some issues from my first test:

  1. At the beginning of round 2, during "PREP COSTUMES" if the moth was camouflaged before, it remains camouflaged even when moved away from the tree.

  2. The set transforms do not persist after the round so every time round 2 ended, I had to refresh and reenter the transforms again before retesting.

  3. Sometimes, the predator enters a loop where it keeps moving towards a moth, trying to eat it and failing. I initially thought it was due to the 3 seconds of round 1 but it repeated in round 2 (see attached video from 10 seconds in).

Still need to test with adjusted (more than 2) rounds.

Simeon

benloh commented 3 years ago

10 seconds

Sorry 'bout that. I think I had committed the 10 second change, then undid it while testing.

MQTT Connect

I'll try to remember to do that. The transforms problem should be fixed with our locale / db feature coming up soon.

  1. camouflaged

The "touches" boundary checking is a little iffy because we're using rectangles for both the bee sprite and the tree. The bee sprite in particular is pretty large, and the tree foliage is deceptive because even though it is round the area being checked is rectangular, which is going to be much bigger than the foilage area. So you might need to make sure you move the moth far away from any trees.

The camouflage test should be run on every loop update, so it should clear itself if it not touching a tree.

This suggests that for your map design you'll want to make sure there are large clear areas.

We can in the future refine the physics engine to do more sophisticated boundary checking, but that does come at a performance cost.

  1. set transforms

Hmmm...interesting. I'm hoping that once we get locales/db working we'll also fix this. Are you setting transforms via the Tracker window? Or do you save the values to dc-inputs? See !104 line 14.

  1. predator loop

Yeah, I've seen that too. I think it might be a pozyx-related bug, or possibly a boundary bug. I'm still trying to chase that one down. The funny thing is it happens at the same spot for me.

benloh commented 3 years ago

marked the checklist item "RESET STAGE" does not work -- scale is not re-applied as completed

benloh commented 3 years ago

added 2 commits

Compare with previous version

benloh commented 3 years ago

marked the checklist item Predator jumps to bottom of screen when trying to eat Moth at -200, -400. See #224. as completed

benloh commented 3 years ago

added 2 commits

Compare with previous version

benloh commented 3 years ago

marked the checklist item CharControl inputs do not seem very responsive as completed

benloh commented 3 years ago

In GitLab by @SimeonOA on Jun 28, 2021, 11:15

Hi @benloh

Thank you for your comments.

I have pulled the latest updates with the fixes and am testing.

RE: transforms. I have been setting via the Tracker window. I will save the values via dc-inputs and see if that solves it.

Thank you

Simeon

benloh commented 3 years ago

added 1 commit

Compare with previous version

benloh commented 3 years ago

added 1 commit

Compare with previous version

benloh commented 3 years ago

added 1 commit

Compare with previous version

benloh commented 3 years ago

added 1 commit

Compare with previous version

benloh commented 3 years ago

added 1 commit

Compare with previous version

benloh commented 3 years ago

marked this merge request as ready

benloh commented 3 years ago

marked the checklist item "Round 1" message displays when you press "SETUP" as completed

benloh commented 3 years ago

In GitLab by @SimeonOA on Jul 6, 2021, 15:45

@benloh We ran into a bug this afternoon while running tests to improve jitter. The bug happened in the middle of testing (we had been testing for about 20 minutes without the bug). When predator is picked up by a tag, before 'Start Round' is clicked, the predator moves as the tag moves. When 'Start Round' is clicked, the predator moves away from the tag and behaves as an AI predator would . In between rounds, the predator return to the tag and is controlled again by the tag.

We do not know what is responsible for this. We were previously on the minirounds branch but I switched to the dev-jd/pilot branch to verify that it was not any changes we made on that branch. We still had the same bug occur.

cc @jdanish and @coreybrady

benloh commented 3 years ago

@SimeonOA After further investigation, the issue is simply that currently when AI is enabled, it will take over the agent regardless of whether it's being controlled by a cursor. I will add a check so that a cursor controlled agent always follows the cursor and disables any AI movements.

benloh commented 3 years ago

Fixed with 89d447f7f7a94c66a80499149bab8a3a248b1955 (Note featProp branch)

benloh commented 3 years ago

added 66 commits

Compare with previous version

benloh commented 3 years ago

Merging so we don't get too far behind.

benloh commented 3 years ago

mentioned in commit e90d6aa5e9c17c2562019125159857cbe7f04513