This site requires JavaScript, please enable it in your browser!
Greenfoot back
thebruus
thebruus wrote ...

2016/11/1

Need to make a sensing mechanism that allows an actor to move towards specks of Dirt

thebruus thebruus

2016/11/1

#
Hey guys! - I'm having a problem with a task where I have to create a robotic vacuum cleaner that needs to move towards specks of dirt whenever they are near. The actor Dirt is placed in random locations on the map whenever reset. Does anyone have any idea what I can do to create a sense() method for my vacuum cleaner to act upon?
Super_Hippo Super_Hippo

2016/11/1

#
Try to use the 'getObjectInRange' method and if something is found, the 'turnTowards' method.
thebruus thebruus

2016/11/2

#
Super_Hippo wrote...
Try to use the 'getObjectInRange' method and if something is found, the 'turnTowards' method.
This is exactly what I've been trying to do actually. But from my understanding I can't turn towards something if their location is randomized and I can't refer to specific coordinates.
thebruus thebruus

2016/11/2

#
this is what i currently have relating to the vacuum actor's sense ability after long hours of trial and error. Now I'm supposedly trying to load an actor before they are spawned, which makes me unable to run the program.
Class Roomba extends Actor

fields:
private static final int sensorRadius = 90
private List dirtInRange = getObjectsInRange(sensorRadius, dirt.class)

public void act()
move()
clean()
sense()

public void sense()
thebruus thebruus

2016/11/2

#
My sense method might be very weird, but I've been trying a lot of different things; here's a pic. http://imgur.com/gallery/v07t2
danpost danpost

2016/11/2

#
thebruus wrote...
My sense method might be very weird, but I've been trying a lot of different things
The code to your sense method is missing. However, line 5 in your code post is trying to execute a collision checking method before the actor is in a world (that line executes when the actor is created). There are only two code starting points where you can use collision checking: the 'act' method and the 'addedToWorld' method, and beyond that startin point, any method that is reached by their execution.
Super_Hippo Super_Hippo

2016/11/2

#
You could try this:
double distance = 100;
Actor nearest = null;
for (Object obj = getObjectsInRange(90, Dirt.class))
{
    Actor a = (Actor) obj;
    double r = Math.sqrt(Math.pow(getX()-a.getX(), 2)+Math.pow(getY()-a.getY(), 2));
    if (r<distance)
    {
        nearest = a;
        distance = r;
    }
}
if (nearest != null)
{
    turnTowards(nearest.getX(), nearest.getY());
}
I hope that the distance calculation is correctly. I just copied it from one of my scenarios and had to change something in it.
thebruus thebruus

2016/11/3

#
Here is the entire code, I think i'm inching towards something right on the sense() method. However I can't figure out how to curb the collision check problem, which, as Danpost pointed out, executes before the actor is in the world.

// WARNING: This file is auto-generated and any changes to it will be overwritten
import java.util.*;
import greenfoot.*;
import java.awt.Color;

/**
 * 
 */
public class Roomba extends Actor
{
    /* constants. speed + capacity + sensingRadius/10 must be 20 or less*/
    private static final int speed = 1;
    private static final int capacity = 10;
    private static final int sensorRadius = 90;
    /* variables*/
    private int capacityLeft = capacity;
    private int dirtCounter = 0;
    private int unloadingDelay = 0;
    /* every Roomba has a Base*/
    public Base myBase = null;
    public Dirt myDirt = null;
    /* a list with dirt around the Roomba (useful for sensing?)*/
    private List<Dirt> dirtInRange = getObjectsInRange(sensorRadius, Dirt.class);

    /**
     * 
     */
    public void act()
    {
        /* the next three lines are required for the delay while unloading the dirt*/
        if (unloadingDelay > 0) {
            unloadingDelay = unloadingDelay - 1;
            return;
        }
        /* the next three lines check whether all dirt (25 pieces) has been removed*/
        if (dirtCounter == 25) {
            Greenfoot.stop();
        }
        move();
        clean();
        sense();
        if (capacityLeft == 0) {
            dump();
        }
        if (capacityLeft > 10) {
            sense();
        }
    }


    public void move()
    {
        move(speed);
        if (isTouching(Barrier.class)) {
            turn(Greenfoot.getRandomNumber(9000));
        }
        if (isAtEdge()) {
            turn(Greenfoot.getRandomNumber(9000));
        }
    }


    public void clean()
    {
        if (isTouching(Dirt.class) && capacityLeft > 0) {
            removeTouching(Dirt.class);
            capacityLeft = capacityLeft - 1;
            dirtCounter = dirtCounter + 1;
        }
    }


    public void sense()
    {
        if (dirtInRange != null && capacityLeft > 10) {
            turnTowards(myDirt.getX(), myDirt.getY());
            move();
            if (isTouching(Dirt.class)) {
                removeTouching(Dirt.class);
            }
        }
    }


    public void dump()
    {
        turnTowards(myBase.getX(), myBase.getY());
        move();
        if (isTouching(Base.class)) {
            unload();
        }
    }

    
    public void unload()
    {
        capacityLeft = capacity;
        unloadingDelay = 1000;
    }
}

thebruus thebruus

2016/11/3

#
Super_Hippo wrote...
You could try this:
double distance = 100;
Actor nearest = null;
for (Object obj = getObjectsInRange(90, Dirt.class))
{
    Actor a = (Actor) obj;
    double r = Math.sqrt(Math.pow(getX()-a.getX(), 2)+Math.pow(getY()-a.getY(), 2));
    if (r<distance)
    {
        nearest = a;
        distance = r;
    }
}
if (nearest != null)
{
    turnTowards(nearest.getX(), nearest.getY());
}
I hope that the distance calculation is correctly. I just copied it from one of my scenarios and had to change something in it.
Thanks! - I'll try to see if I can figure out how to add this, and see if it works!
danpost danpost

2016/11/3

#
thebruus wrote...
I can't figure out how to curb the collision check problem, which, as Danpost pointed out, executes before the actor is in the world.
With the code Super_Hippo supplied, you can just remove line 23 (from your last posting of the Roomba class). If you use '/**', with two asterisks, for your multi-line comment blocks (whether they are actually multi-line or not), your code will display better here.
You need to login to post a reply.