Restrictions setting examples

This article is automatically translated from Russian by Google Translator.

Setting constraints is a unique feature of TRIK Studio designed for an automated check of tasks. This tool has many uses:

  • self-examination of homework by students,

  • accelerating the process of checking tasks by the teacher,

  • online competitions with automatic checking of the participants' solutions.

The TRIK Studio constraint language is a very powerful tool that allows you to check almost all aspects of program execution and robot behavior and may seem complicated at first glance. However, don't be upset - in this article we will walk you through the process of creating constrained tasks, ranging from simple constraints that cover most of the tasks to complex constraints, which can be useful for enthusiasts.

Restricting the program execution time and the "Start" and "Finish" zones

For those who are just starting to get acquainted with the TRIK Studio constraint language, we suggest starting with simple restrictions on the program run time, the "Start" and "Finish" zones. This is more than enough for most robotic tasks.

1. Define the following conditions and parameters for the task and the world model.

  • Optimal program execution time. If the program exceeds the timelimit, the checking system will generate an error "The program ran too long".

  • Start zone. The zone from which the robot must start executing the program, otherwise the checking system will generate an error.

  • Finish zone. The zone where the robot must arrive at the end of the program, otherwise the checking system will generate an error.

2. Edit the value of the <regions> tag in the world XML file to add the Start and Finish zones. By changing the x, y, width and height values, you can edit the location and size of the zones. To check the position of a zone, load the file into the virtual world model and check the location of the zones. After that, if necessary, you can make the "Start" and "Finish" zones invisible by setting the attribute visible="false".

3. Copy the <constraints> block template below into the XML file of the world for which you want constraints.

4. Fill in the <timelimit value="300000"> tag. Specify what you think is the best execution time for the program. Note that the time is in milliseconds, i.e., 300000ms = 5 minutes, 120,000ms = 2 minutes, etc.

5. The constraint task is ready! Now you know how to check the start and end positions of the robot and the execution time of the program.

Examples analysis

Now let's break down the application of this technique to different tasks and consider options for more detailed checks.

Example 1. Drive from the "Start" zone to the "Finish" zone with a restriction of the movement zone

The task of passing the labyrinth. Having started in the blue square, it is necessary to pass to the finish area. In order to check that the user actually passes the labyrinth and not bypasses it, a spatial constraint is set.

Blue square - start area, red square - finish area, black rectangle - field that cannot be left by the robot

Below is the complete code to test this task.

Let's take a closer look at how the check takes place.

1. Set a time limit for passing the task. This limit is mandatory. The time is specified in milliseconds.

2. Set a constraint on the area where the robot should be before starting the program. According to the condition of the problem, it should be a blue square - the start area. This restriction will be checked once, at the beginning of the program, since the attribute checkOnce is true.

With the <inside> tag we set the spatial constraint. It has two attributes. In the first (objectId) we specify the id of the object whose location we want to check, in our case, it is a robot. In the second (regionId) we specify the id of the region in which our object should be located.

If the condition described in <inside> is not met, the program will be terminated with an error. For this, the <constraint> tag has an attribute failMessage, which allows you to specify the text of the error message.

3. In order to verify that the user actually goes through the maze and not bypasses it, let's set another spatial constraint.

Let's edit the <regions> tag in the XML file of the world by adding the region with id = "warzone".

This constraint will be checked at all times of program execution. In the <inside> tag we will specify the object id and the region id, in our case, it is the robot and the black rectangle limiting the maze.

If the robot is outside the specified region at any time, the program will terminate with an error, the text of which is specified in the failMessage attribute.

4. Now we have to check that the robot reaches the finish area.

To do this, let's create an event that will check if the robot is in the right zone or not. The attribute settedUpInitially="true" means that the event will be started (fired) immediately when the program starts.

In the <condition> tag we specify which condition to check. In our case the condition is the same as described above - we are checking that the robot is in the region with id = "finish". If that condition is true, then the user will see a message saying that the program was executed successfully. To do that, we write a child tag <success/> in the <trigger> tag.

Example 2. Drive from the "Start" zone to the "Finish" zone with a stop

The task is to pass forward and stop in the finish area.

This task is slightly different from Example 1 in that another condition is added for successful completion of the program - the robot must not only be in the finish area, but also stop.

Below is the complete code to test this task.

Now let's take a closer look at how the check takes place.

1. Let's set a time limit for passing the task.

2. Let's set a constraint on the initial position of the robot. It will be checked once at the beginning of the program.

3. Set a restriction on the area that the robot cannot leave.

4. Now create an event that verifies that the robot is in the finish zone and that it has stopped in the finish zone and has not moved on.

The zone limit is set with the <inside> tag. In order to check that the robot has stopped, we need to check that the power on both motors is zero. To do this we use the <equals> tag. With the <objectState> tag we define the object whose value we want to compare. In our case this is the power of the motors, so we will write robot1.M3.power or robot1.M4.power in the attribute object, where M3 and M4 are the ports to which the motors are connected in the current configuration. And the value to be compared we write using the <int> tag and its value attribute.

Thus, this event checks three conditions: the robot is in the finish area, the power on motor M3 is zero and the power on motor M4 is also zero. If these conditions are met the user will be shown a message about the successful execution of the program.

Example 3. Drive from the "Start" zone to the "Finish" zone along the wall with the sensors checking

Having started in the blue square, you must drive along the wall with the IR distance sensor to the red square.

Below is the complete code for checking this task.

Now let's take a closer look at how the check takes place.

1. Let's set a time limit for the task.

2. According to the problem condition, the robot must have only the distance sensor connected (there must be no other sensors). To be sure of this, let's compare the value of the object on port A1 with the value of the distance sensor. For more information about the names of the sensors for different constructors, see the link.

3. Let's check that no sensors are connected to the other ports. To do this, compare the value on each port with the "undefined" string.

4. Let's set a constraint on the initial position of the robot. It will be checked once at the beginning of the program because the checkOnce flag is set.

5. Let's set a restriction on the zone that the robot can't leave. In the previous examples, we considered a situation where the robot needed to stay in one zone. In this case, the allowed zone consists of several rectangles, so we need to check that the robot is in one of those zones. To do that we use the <conditions></conditions> tag with the glue = "or" attribute.

6. Finally, let's create an event that will notify you if the robot is in the finish area.

Example 4. Counting intersections and displaying the result

Linear traffic with intersection counting: when entering an intersection, the robot should display the number of this intersection on the screen.

Below is the complete code for checking this task.

Let's take a look at how verification works.

1. After each intersection, set the zones where it will be checked that the correct intersection number is displayed. To do this, edit the value of the <regions> tag in the XML file of the world, adding there the necessary number of zones to check. By changing the values of x, y, width and height, you can edit the location and size of the zones. To check the position of a zone, load the file into the virtual world model and check the location of the zones. After that, if necessary, you can make zones invisible by setting the attribute visible="false".

2. After that, in the <constraints> block set the constraint check. First we will specify the limit on the execution time of the task.

3. Let's set a constraint on the initial position of the robot.

4. In each zone after the intersection, we will check that the correct number is displayed. To do this, specify the id of the desired region in the <inside> tag and check that the last displayed message (robot1.display.labels.last.text) equals the number of the passed intersection. After that, we will call the same events for the rest of the zones.

5. We will display an error message if the wrong number is displayed. To do this, compare the message that was displayed with the expected correct value. If the messages don't match, the user will get the specified error message and the program will stop executing.

6. Set the event that will display a message about the successful execution of the program, if all the specified intersections are passed correctly.

Example 5. Kegelring

The robot must push all pins outside the circle.

Below is the complete code for checking this task.

Now let's look in more detail at how the check takes place.

1. Let's edit the XML file of the world by adding a circle zone to the <regions> tag.

2. Let's set a time limit for the task.

3. Let's set a constraint on the initial position of the robot.

4. Set an event that checks that all pins are outside the circle, and then displays a message that the program has been successfully executed.

Example 6. Checking robot behavior

In the start position the robot must be in the start area at a distance from the wall and a touch sensor must be connected to port A1. A successful pass is when the robot approaches the wall, touches it with the touch sensor, moves away from it, and so on 5 times.

The idea of the checking program is that at any given time either the event waiting for the robot to drive up to the wall or that it has gone back is triggered. Both of these events arm each other. When the robot returns to its original position, the iteration counter is incremented. There is an extra event that checks the counter value. It will display a message about the successful execution of the program when the value is five.

Below is the complete code for checking this task.

Now let's take a closer look at how the check takes place.

1. Let's set a time limit for the task.

2. According to the problem condition, the robot must have only the touch sensor connected (there must be no other sensors). To be sure of this, compare the value of the object on port A1 with the value of the touch sensor. For more information about the names of the sensors for different constructors, see this link.

3. Let's check that no sensors are connected to the other ports. To do this, compare the value on each port with the "undefined" string.

4. Set a restriction on the area that the robot cannot leave.

5. Let's set an event that verifies that the robot has started to move forward. As a condition, we specify that the power applied to the motor on port M3 must be greater than zero. If this condition is fulfilled, two triggers are triggered. The first one triggers the event with id = "Touching wall", and the second one assigns the value zero to the variable counter.

Since the attribute settedUpInitially is set to true, the event will be triggered (activated) immediately at the program startup.

6. Let's define an event that will show an error in case after 1000ms (=1sec) the robot hasn't started moving forward (i.e. the event with id="First move" is still on and hasn't been executed). Since several conditions are checked in this event, the <conditions></conditions> tag is used with the logical connectors.

7. Set an event that checks that the robot has traveled to the wall. The condition checks that the value of the touch sensor located on port A1 is one (this means that the touch sensor has been triggered). If this condition is met, the trigger is triggered and the event id="Returned back" is triggered.

8. Let's define an event that checks if the robot has returned to the start zone after touching the wall. To do this, we need to set an inside condition with attributes objectId="robot1" (our robot) and regionId="start_zone" (the zone to return to).

When this condition is met, two events are triggered and the iteration counter is incremented. The first event checks if the robot has touched the wall, the second event checks if the problem condition has been met.

9. Let's set an event that will display a message about the successful execution of the program if the value of counter is at least 5.

Last updated

Was this helpful?