Random creator missing from Connect

Hi there! I’ve been experimenting with Prototwin Connect and an S7-1200 Siemens PLC. It’s really a promising platform and I could get started easily reading the docs. Onshape integration is also handy.

My problem is that I’d like to model a copy of a plant that sorts boxes of different sizes so I’d need to create such boxes with random intervals and random sizes. Reading the docs I learned about the Creator component which shows a Random Creator component but there’s no such component in the Connect desktop app. Is there some workaround to get my desired behavior?

Thanks!

Hi Leonardo,

The random creator component in the documentation is used to illustrate how you can create your own custom creator components. We don’t have a built-in random creator, because there are too many possibilities. Some use cases will call for randomizing position, others rotation or maybe cycle between creating different entities. Any component that covers most possibilities will be too complex and time-consuming to configure for most people.

The AI assistant in the script editor should be able to generate a component that can randomize the scale of the entity being duplicated without any issues. For example, I asked the assistant the following:

Write a custom creator component that duplicates an entity with a random scale and at a random interval between some configurable minimum and maximum values.

And it generated this component:

import { CreatorComponent, Entity, Random, Units, UnitType } from "prototwin";

export class RandomEntityCreator extends CreatorComponent {
    @Units(UnitType.Time)
    public minInterval: number = 1.0;

    @Units(UnitType.Time)
    public maxInterval: number = 3.0;

    public minScale: number = 0.5;
    public maxScale: number = 1.5;

    #timer: number = 0;
    #currentInterval: number = 0;

    public constructor(entity: Entity) {
        super(entity);
    }

    public override initialize(): void {
        super.initialize();
        this.#calculateNextInterval();
    }

    public override update(dt: number): void {
        this.#timer += dt;

        if (this.#timer >= this.#currentInterval) {
            this.#timer = 0;
            this.#calculateNextInterval();

            this.createCustom((entity) => {
                entity.scale = Random.global.nextNumber() * (this.maxScale - this.minScale) + this.minScale;
            });
        }
    }

    #calculateNextInterval(): void {
        this.#currentInterval = Random.global.nextNumber() * (this.maxInterval - this.minInterval) + this.minInterval;
    }
}

If you need additional functionality, you can make follow-up requests. For example:

Add a congestion zone, sized according to the largest possible entity that can be created.

Which resulted in the following component:

import { CreatorComponent, Entity, PhysicsQuery, Random, Units, UnitType } from "prototwin";

export class RandomEntityCreator extends CreatorComponent {
    @Units(UnitType.Time)
    public minInterval: number = 1.0;

    @Units(UnitType.Time)
    public maxInterval: number = 3.0;

    public minScale: number = 0.5;
    public maxScale: number = 1.5;

    #timer: number = 0;
    #currentInterval: number = 0;

    public constructor(entity: Entity) {
        super(entity);
    }

    public override initialize(): void {
        super.initialize();
        this.#calculateNextInterval();
    }

    public override update(dt: number): void {
        this.#timer += dt;

        if (this.#timer >= this.#currentInterval) {
            if (!this.#isCongested()) {
                this.#timer = 0;
                this.#calculateNextInterval();

                this.createCustom((entity) => {
                    entity.scale = Random.global.nextNumber() * (this.maxScale - this.minScale) + this.minScale;
                });
            }
        }
    }

    #isCongested(): boolean {
        const originalScale = this.entity.scale;
        this.entity.scale = this.maxScale;
        const detected = PhysicsQuery.boundingBox(this.entity, true);
        this.entity.scale = originalScale;

        if (detected === null || detected === this.entity || this.entity.ancestorOf(detected)) {
            return false;
        }

        return true;
    }

    #calculateNextInterval(): void {
        this.#currentInterval = Random.global.nextNumber() * (this.maxInterval - this.minInterval) + this.minInterval;
    }
}

To use the component, you just need to copy the code and paste it into a new script file. You should then be able to add the component to the entity that you want to be duplicated.

The assistant is quite capable. You just need to ensure that you provide it with sufficient detail and context. We have a short video that demonstrates using the assistant. If you need something that the assistant cannot handle, please let us know and we’ll gladly create and publish it to the package manager.

Thanks for helping. I’ll try what you suggest.

It works just fine. The AI assistant proved really useful. Thanks again for helping.

1 Like