question

Patrick Crowley avatar image
2 Likes"
Patrick Crowley asked Matthew Gillespie commented

Setting the location of a rack after resizing it

Hello,

I am trying to generate copies of a rack onReset, then change their dimensions using the BasicRefreshTable function, according to parameters I am reading in from a global table. When I change their dimension however, their locations in the simulation change as well. I tried saving their previous locations using the xloc() and yloc() functions, then restoring them using setloc(), but xloc and yloc seem to measure relative position while setloc is absolute position.

Is there a good way to get the location of an object relative to its container, so that I can use setloc? The racks are resizing correctly, but the ones that are changed are moved pretty significantly. Additionally, their parents object (a plane) is staying in its original location, so it isn't an issue of scope.

I did try changing the coordinate center of the rack. Regardless of if I used corners, planar mid points, the object center, or direct spatials, the result was always the same.

Any help or advice is appreciated, thanks!

FlexSim 17.2.1
rackonresetsetlocbasicrefreshtable
· 1
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Patrick Crowley avatar image Patrick Crowley commented ·

In case it's helpful, here's the code that is editing the racks. There are a number x picking zones (already generated at this point), each containing 2 racks, where y is the rank of the rack in that zone. It is iterating through each zone and each rack, then updating the dimensions from the corresponding column in the table "RackDimensions". The treenode PickingPlane is the parent object of all the zones, and the RackPlane is the parent of the racks in each zone (and is the first node under each picking zone).

Additionally, the displacement of the rack seems to be proportional to how many bays I am adding or taking away, compared to the original size.

// update Rack dimensions
if(gettablecols("RackDimensions") == content(PickingPlane)) { // number of columns must match the number of picking zones otherwise onReset trigger will not resize the racks
	for(int x = 1; x <= content(PickingPlane); x++) {
		for(int y = 1; y <= content(first(rank(PickingPlane, x))); y++) { // y is number of rack
			double xcor = relloc(rank(first(rank(PickingPlane, x)), y), up(rank(first(rank(PickingPlane, x)), y)), 1);
			double ycor = relloc(rank(first(rank(PickingPlane, x)), y), up(rank(first(rank(PickingPlane, x)), y)), 2);
		
			function_s(node("/?Rack", library()), "BasicRefreshTable", rank(first(rank(PickingPlane, x)), y), gettablenum("RackDimensions", 1, x), gettablenum("RackDimensions", 2, x), gettablenum("RackDimensions", 3, x), gettablenum("RackDimensions", 4, x));
			setloc(rank(first(rank(PickingPlane, x)), y), xcor, ycor, 0);
			
		}
	}
}
1 Like 1 ·

1 Answer

Matthew Gillespie avatar image
1 Like"
Matthew Gillespie answered Matthew Gillespie commented

Resizing a rack doesn't change the rack's location. Take a look at this sample model to see what I mean. I'm using this code to resize the rack and to print out the location before and after:

Object rack = model().find("Plane3/Rack1");
int numLevels = 10;
int numBays = 10;
double levelHeight = 1;
double bayWidth = 1;

print("Location before:\t", rack.location, "\tCenter Location before:\t", rack.getLocation(0.5, 0.5, 0));

function_s(node("/?Rack", library()), "BasicRefreshTable", rack, numLevels, numBays, levelHeight, bayWidth);
			
print("Location after:\t", rack.location, "\tCenter Location after:\t\t", rack.getLocation(0.5, 0.5, 0));

Using this script to change the number of bays from 10 to 20 gave this output:

Location before: Array[3]: {3,-3,0}  Center Location before: Array[3]: {8,-4,0}
Location after:	 Array[3]: {3,-3,0}  Center Location after:  Array[3]: {13,-4,0}

As you can see, the location doesn't change, but the location of the center of the rack does change in the x direction. The location of an object is measured from the top left corner on the bottom of the object before any rotations are applied. When you resize the rack this point doesn't move.

However, the value you see in quick properties is, by default, showing you the location relative to the center of the bottom of the object (You can change this using the button next to the location fields). So, since you're widening the rack's dimensions the center is going to shift by half that amount. I'm measuring that point using the getLocation method with a 0.5 xFactor, 0.5 yFactor, and 0 zFactor (the bottom center of the object).


resizerack.fsm (14.8 KiB)
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Patrick Crowley avatar image Patrick Crowley commented ·

Thanks for the reply. So if I wanted to maintain the racks's position relative to a queue at one end of it for example, what is the best way to go about retaining the original center location?

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Patrick Crowley commented ·

You should use the getLocation and setLocation methods of the Object class. These methods let you specify a point on the object where the location will be measured from. You specify a factor (between 0 and 1) for each direction (X, Y, and Z). So to maintain the center position of the object you would say:

Object rack = model().find("Plane3/Rack1");
Vec3 factors = Vec3(0.5, 0.5, 0);

Vec3 initialPosition = rack.getLocation(factors);
//Resize rack
rack.setLocation(initialPosition, factors);

You can use a different set of factors to maintain the position relative to a different point on the object.

1 Like 1 ·