Posts: 1
Threads: 1
Joined: Apr 2015
Reputation:
0
Country:
How do I get a grabber to only collect Powercells that needs to be charged?
Code: extern void object::Findandcharge()
{
object item;
while(true)
{
item=radar(PowerCell);
while ( item.energyLevel < 1 )
{
goto(item.position);
grab();
}
}
}
Posts: 157
Threads: 5
Joined: Mar 2013
Reputation:
60
Hello.
Problem of finding and recharging power cells can be divided in two parts. First one is to find all power cells that need to be recharged. Second, recharge all found power cells.
First part is to make a list for power cells. We can use empty list of objects to store them:
Code: // list of power cells to recharge
object[] list;
To find all power cells we need to use retobject() function. We need to iterate over all objects in the world, see if given object is power cell, whether it is carried by something else and, finally, if it needs to be recharged. Then we add it to the list.
Code: // find all power cells to recharge
for(int i=0, j=0; ; i++)
{
// next object
object item = retobject(i);
// no more items
if(item == null) break;
// item is not power cell
if(item.category != PowerCell) continue;
// power cell was put in some other object
if(item.position.x == nan) continue;
// power cell has less than 100% energy
if(item.energyLevel < 1.0)
{
// add to list
list[j++] = item;
}
}
Then we actually recharge all power cells. We iterate over our list, find each power cell and recharge it:
Code: // recharge all power cells
for(int i=0; i<sizeof(list); i++)
{
// take next power cell
object item = list[i];
goto(item.position);
grab();
// find and go to power station
item = radar(PowerStation);
goto(item.position);
// recharge power cell
while(this.load.energyLevel < 1.0)
{
wait(0.1);
}
// find free space and drop power cell
goto(space());
drop();
}
If you put together all the above code, you get complete solution to your problem. I hope that helped.
"After three days without programming, life becomes meaningless."
~The Tao of Programming
Posts: 21
Threads: 3
Joined: Nov 2015
Reputation:
6
12-04-2015, 04:13 PM
(This post was last modified: 12-05-2015, 03:13 AM by krakers.
Edit Reason: i placed "[/code]" in wrong place
)
Hello,
Im quite new in programming (last time i was trying 10 years ago - in Colobot too) and i have problem with my program. I have no idea how to solve it.
I want it to:
1) find fully charged NuclearCell and grab it
2) find a robot with empty NuclearCell, go there
3) exchange him Cell to fresh one
So i wrote that code:
Code: extern void object::Power_Rescue()
{
while (true)
{
if (this.load != null)
{
goto(space(position));
drop();
}
FindFullCell();
FindEmptyCell();
ChangeCell();
wait(10);
}
}
void object::FindFullCell()
{
while (true)
{
object[] list;
for (int i=0, j=0;; i++)
{
object item = retobject(i);
if (item == null) break;
if (item.category != NuclearCell) continue;
if (item.position.x == nan) continue; // jesli ogniwo nie jest w robocie
if (item.energyLevel == 1)
{
list[j++] = item;
}
}
for (int i=0; i < sizeof(list); i++)
{
object item = list[i];
goto(item.position);
grab();
break;
}
break;
}
}
void object::FindEmptyCell()
{
object item;
int j;
object[] list;
for (int i=0, j=0;; i++)
{
object item = retobject(i);
if (item == null) break;
if (item.category != NuclearCell) continue;
if (item.position.x != nan) continue; // jesli ogniwo nie jest w robocie
if (item.energyLevel < 0.1)
{
list[j++] = item;
}
}
for (int i=0; i < sizeof(list); i++)
{
object item = list[i];
goto(item.position);
}
}
void object::ChangeCell()
{
turn(90);
drop();
turn(-90);
grab();
turn(-90);
drop();
turn(180);
grab();
turn(-90);
drop();
}
So, FindFullCell works fine and the problem is with FindEmptyCell - it finds a cell with position.x == null, so that cell is installed in robot and that's good. But how the robot can goto robot's position, while the position (of cell) == null ? How to get a position of the robot?
P.S. I know there may be a lot of bugs in program and maybe it's not well iptimized but its my third day, so I'm just a begginer.
Posts: 43
Threads: 10
Joined: Sep 2015
Reputation:
21
12-04-2015, 06:55 PM
(This post was last modified: 12-04-2015, 07:47 PM by melex750.)
This seems like a good place to mention the new radarall() function, dev version only, for now.
object[] list;
list = radarall(PowerCell); // returns all PowerCells on the ground.
Posts: 21
Threads: 3
Joined: Nov 2015
Reputation:
6
So for version Alpha 0.1.6 its impossible to make a program i want to make?
Posts: 43
Threads: 10
Joined: Sep 2015
Reputation:
21
12-05-2015, 01:28 AM
(This post was last modified: 12-05-2015, 04:11 AM by melex750.)
It's not impossible.
I'm testing your program now.
Your program needs to be modified to search for a "robot" which has an empty PowerCell.
Wow that was tough. I re-wrote most of it. Tell me if you find any bugs.
Code: extern void object::Power_Rescue()
{
while (true)
{
if (this.load != null)
{
goto(space(position));
drop();
}
FindObjectReplaceCell();
if (this.load != null) continue;
wait(10);
}
}
void object::GrabNearestFullCell()
{
object item, NearestItem = null;
int i = 0;
while (true)
{
item = retobject(i++);
if (item == null) break;
if (item.category != NuclearCell) continue;
if (item.position.x == nan) continue;
if (item.energyLevel == 1)
{
if (NearestItem == null)
{
NearestItem = item;
continue;
}
if (distance(this.position, item.position) < distance(this.position, NearestItem.position) )
{
NearestItem = item;
}
}
}
if (NearestItem == null) return; // did not find an item
goto(NearestItem.position);
grab(InFront);
return;
}
void object::ChangeCell()
{
drop(Behind);
grab(InFront);
turn(-90);
drop(InFront);
turn(90);
grab(Behind);
drop(InFront);
turn(-90);
grab(InFront);
}
void object::FindObjectReplaceCell()
{
object item;
int i = 0, t = 0;
float speed;
int types[];
types[t++] = WheeledShooter;
types[t++] = WheeledGrabber;
types[t++] = TrackedGrabber;
while (true)
{
item = retobject(i++);
if (item == null) break;
for (int k = 0; k < sizeof(types); k++)
{
if (item.category == types[k]) // must be in the list
{
if (item.id == this.id) break; // <--------- not this bot
if (item.energyCell == null)
{
message("INFO: "+item.category+" Has No energyCell");
break; //<--------------------------------------- must have an energyCell
}
if (item.energyCell.energyLevel < 0.1)
{
if (item.velocity.x != nan)
{
speed = abs(item.velocity.x);
speed += abs(item.velocity.y);
speed += abs(item.velocity.z);
} else speed = 0.0;
if (speed != 0.0 and item.altitude > 0.0) break;// not moving or flying
GrabNearestFullCell();
if (this.load == null) return; // did not find a FuelCell
goto(item.position);
ChangeCell();
return;
}
}
}
}
return;
}
Posts: 21
Threads: 3
Joined: Nov 2015
Reputation:
6
Works perfect, thank You!
Now I can go to bed
Posts: 18
Threads: 7
Joined: May 2016
Reputation:
0
05-03-2016, 12:42 PM
(This post was last modified: 05-03-2016, 12:45 PM by clop1000.)
melex750 excellent job!
But - what is the meaning of this part of code? -
if (item.velocity.x != nan)
{
speed = abs(item.velocity.x);
speed += abs(item.velocity.y);
speed += abs(item.velocity.z);
} else speed = 0.0;
And for what purpose do you use line with - return; and nothing more? What is it doing?
Posts: 157
Threads: 5
Joined: Mar 2013
Reputation:
60
Quote:if (item.velocity.x != nan)
{
speed = abs(item.velocity.x);
speed += abs(item.velocity.y);
speed += abs(item.velocity.z);
} else speed = 0.0;
This code calculates linear speed of some object, although it's not a mathematically correct code. Properly, linear velocity is a square root of sum of squares of velocity components in all dimensions, so:
Code: float vx = item.velocity.x;
float vy = item.velocity.y;
float vz = item.velocity.z;
float speed = sqrt(vx * vx + vy * vy + vz * vz);
Comparing a value for NaN is necessary because some objects have invalid velocity.
If you want linear velocity in horizontal plane, just skip third component Z.
return without value is used to return from void function, but it's not necessary to put it at the end of function because it doesn't do anything.
"After three days without programming, life becomes meaningless."
~The Tao of Programming
Posts: 18
Threads: 7
Joined: May 2016
Reputation:
0
Thx! it's really good explanation!
Posts: 18
Threads: 7
Joined: May 2016
Reputation:
0
Is there any way to get a reference on the holder of PowerCell?
For instance - i got a list of PowerCells, and i want tot know, which of them are installed in bots.
object.load - does not work properly .
Posts: 828
Threads: 26
Joined: Oct 2012
Reputation:
113
07-05-2016, 01:10 PM
(This post was last modified: 07-05-2016, 01:11 PM by krzys_h.)
I don't think there is a way to do that. You have to iterate through all objects and check therir .energyCell property.
Posts: 263
Threads: 3
Joined: Dec 2012
Reputation:
18
There is a way, but you'd need identify to Power Cell as one that's being hold (By position.x == NaN (?)), then save it's id, and then sift though every object and check if it has load, and if yes then what's its id
"Deep within all of us lives an idiot, and if you let that idiot dictate your decisions your live is going to be rough."
~ Ryan Letourneau, 2k15
Posts: 43
Threads: 10
Joined: Sep 2015
Reputation:
21
@ clop1000 ,
This program can get the holder of any object that can be carried.
Code: extern void object::Example()
{
// list of objects that can be carried
object obj[];
// ...fill the list...
object holder = GetOwnerOf( obj[0] );
// if this robot has obj[0]
if (holder == this) /* do stuff */ ;
// if obj[0] is on the ground or obj[0] == null
else if (holder == null) /* do stuff */ ;
// if obj[0] is in battery slot of holder
else if (obj[0] == holder.energyCell ) /* do stuff */ ;
// if obj[0] is carried in claw of holder
else if (obj[0] == holder.load ) /* do stuff */ ;
}
public object object::GetOwnerOf(object obj)
{
if (obj == null) return null;
if (obj.position.x != nan) return null; // obj is on the ground
if (obj == this.energyCell) return this;
if (obj == this.load) return this;
int types[] = ObjectHolders();
object objList[] = radarall(types); // find all object holders
int numObjs = sizeof(objList);
for (int i = 0; i < numObjs; i++) // check if one holds obj
{
if (obj == objList[i].energyCell) return objList[i];
if (obj == objList[i].load) return objList[i];
}
return null;
}
int[] ObjectHolders()
{
int i=0;
int list[];
list[i++] = WingedGrabber;
list[i++] = TrackedGrabber;
list[i++] = WheeledGrabber;
list[i++] = LeggedGrabber;
list[i++] = WingedShooter;
list[i++] = TrackedShooter;
list[i++] = WheeledShooter;
list[i++] = LeggedShooter;
list[i++] = WingedOrgaShooter;
list[i++] = TrackedOrgaShooter;
list[i++] = WheeledOrgaShooter;
list[i++] = LeggedOrgaShooter;
list[i++] = WingedSniffer;
list[i++] = TrackedSniffer;
list[i++] = WheeledSniffer;
list[i++] = LeggedSniffer;
list[i++] = Thumper;
list[i++] = PhazerShooter;
list[i++] = Recycler;
list[i++] = Shielder;
list[i++] = Subber;
list[i++] = DefenseTower;
list[i++] = ResearchCenter;
list[i++] = PowerPlant;
list[i++] = NuclearPlant;
list[i++] = AutoLab;
//list[i++] = AlienWasp; // wasp can carry objects too
return list;
}
This can also be done with a method called on the object, but that is slightly more complicated.
|