I'm trying to create a curved one-way AGV path in FlexScript, given:

- The starting point
- The start angle
- The sweep angle
- The radius

**TL;DR: Please help me write a function that works for all reasonable (0 <= ... < 360) angles.**

I found that applyDragStart and applyDragEnd don't respect the angles so my best bet was to create a path with the given angles and radius, then find its starting point, and shift it to the position I want it.

In the screenshot below, the straight path has a 'direction' of -135 (where 0 is the model x-axis). The two selected arcs have a start angle of 45 (apparently for the AGV network, 0 is the y-axis) and sweep angles of 90 and -90 respectively. As you see, one of them (the positive sweep angle) is correct but the other one is rotated or mirrored relative to what I want.

In addition, when trying to calculate the shift needed I tried to find the starting point using

Vec3 startOfPath = path.location + Vec3( -radius * Math.sin( sweepAngle ), radius * Math.cos( sweepAngle ), 0 );

but sometimes that gives me the starting point, and sometimes the end point (that is, I get one endpoint of the path but not necessarily the correct one according to the path direction).

Here is what I tried, but that only seems to work correctly in some arbitrary cases.

// Note: AGV directions are rotated 90 degrees (0 = positive y) setvarnum( path, "startAngle", -Math.degrees( pathDirection ) - 90 ); setvarnum( path, "sweepAngle", angle ); setvarnum( path, "radius", radius ); function_s( path, "setZ", point.z, /* isStart: */ 1 ); function_s( path, "finalizeSpatialChanges" ); double secSweepRad = Math.radians( angle ) - pathDirection; Vec3 startOfPath = path.location + Vec3( -radius * Math.sin( secSweepRad ), radius * Math.cos( secSweepRad ), 0 ); path.location += point - startOfPath; function_s( path, "finalizeSpatialChanges" );

Please help me write this function or at least understand how the AGV paths work without having to reverse engineer it :-)

createagvpath.png
(3.3 KiB)

Comment

Best Answer

**Answer** by phil.bobo ·

A curved path's definition is based on a position (of the center of its circle), a start angle, a sweep angle, and a radius.

If you define it in terms of a start position instead of a position that is based on the center of its circle, then what does "start angle" mean? What does "sweep angle" mean?

For the AGV network, the start and sweep angles are relative to a unit circle where the FlexSim x axis is the x axis and the FlexSim y axis is the y axis. I don't know what you mean by "apparently for the AGV network, 0 is the y-axis." 0 represents the positive x axis, not the y axis.

The following code creates and positions a curved agv path based on the inputs that it expects:

Object path = createinstance(node("/AGV/CurvedPath",library()),model()); Vec3 pos = [0, 0, 0]; double startAngle = 10; double sweepAngle = 45; double radius = 2; setvarnum(path, "startAngle", startAngle); setvarnum(path, "sweepAngle", sweepAngle); setvarnum(path, "radius", radius); path.location = pos; function_s(path, "finalizeSpatialChanges");

The following code shifts the curve so that its location is adjusted based on a specified starting point:

Model.find("AGVNetwork").subnodes.clear(); Object path = createinstance(node("/AGV/CurvedPath",library()),model()); double startAngle = 0; double sweepAngle = 45; double radius = 2; setvarnum(path, "startAngle", startAngle); setvarnum(path, "sweepAngle", sweepAngle); setvarnum(path, "radius", radius); Vec3 startPoint = [2, 1, 0]; double x = startPoint.x - radius * Math.cos(startAngle * (pi/180)); double y = startPoint.y - radius * Math.sin(startAngle * (pi/180)); double z = startPoint.z; path.location = Vec3(x, y, z); function_s(path, "finalizeSpatialChanges");

I don't understand your explanation of what you want from your image of selected paths. If one of them has a sweep angle of 90 and the other has a sweep angle of -90, then of course they are going to appear to be mirrored; their angles are sweeping in opposite directions.

If you are trying to define the curves in your picture that aren't selected, this is how they are defined by FlexSim:

If you want to define your curves another way, then you need to convert from how you want to define them into that format. That's the input format that FlexSim's curved paths are defined by.

Thanks, your explanation really helped me understand how it works.

I did have to fiddle a bit with some minus signs, but my final solution is pretty close to yours (pathDirection is the direction we were travelling in on the straight path)

double startAngle = Math.pi / 2 - (Math.fabs(pathDirection) > Math.pi ? -1 : 1) * pathDirection; if( sweepAngle < 0 ) { startAngle *= -1; } setvarnum( path, "startAngle", -Math.degrees( startAngle ) ); setvarnum( path, "sweepAngle", sweepAngle ); setvarnum( path, "radius", radius ); path.location = point + Vec3( -radius * Math.cos( startAngle ), radius * Math.sin( startAngle ), 0 );

© 1993- FlexSim Software Products, Inc. All Rights Reserved.

FlexSim is a fully 3D simulation software environment. FlexSim can be used to simulate any process in any industry.

FlexSim®, FlexSim Healthcare™, Problem Solved.®, the FlexSim logo, the FlexSim X-mark, and the FlexSim Healthcare logo with stylized Caduceus mark are trademarks of FlexSim Software Products, Inc. All rights reserved.

- site links
- www.flexsim.com
- contact us
- blog
- privacy policy
- archived forum

- Anonymous
- Sign in
- Create
- Ask a question
- Post an idea
- Create an article
- Spaces
- Software & Simulation Questions
- Accounts & Licensing
- FlexSim
- FlexSim Healthcare
- Explore
- Topics
- Questions
- Ideas
- Articles
- Users
- Badges