text:
# What does the AspectRatio option actually do?

The Documentation for AspectRatio on its first line under the "Details" section states: "AspectRatio determines the scaling for the final image shape" (emphasis is mine). But the practice shows that is it not true: it seems that this option affects only aspect ratio of the plot range but not the aspect ratio of the whole image (with ImagePadding and ImageMargings added). It is a basic graphics option but we still know a little about it...

What the option AspectRatio actually do? How it interacts with PlotRangePadding, ImagePadding, ImageMargings and ImageSize?

It would be ideal to have a mathematical model of interaction between these options.

• possible duplicate of AspectRatio option works unpredictably? – David G. Stork May 18 '15 at 18:15
• @David My intention was to create a summary question where many aspects of working of the AspectRatio options would be summarized and cleared out. That question was too highly specialized, this is intended as a clarification of the Documentation for AspectRatio which is misleading. – Alexey Popkov May 18 '15 at 18:21
• It seems to me that a mathematical model would be exceedingly complicated to arrive at in this case. The aspect ratio one calculates from the dimensions of a rasterized output depends on how much space had to be allocated to things like ticks and axes etc. This in turn depends not only on the data to be plotted, but also on adventitious parameters such as font size, tick choice, etc. – MarcoB May 18 '15 at 18:50
• @MarcoB The mathematical model may describe just relationships between numerical values of parameters and do not account for symbolic values (such as All etc.). In this case font size, tick choice, etc. does not matter. – Alexey Popkov May 19 '15 at 0:14
• This question has my support. If I have time it will also have my answer. – Mr.Wizard May 19 '15 at 3:40

Without padding of any kind the over-all aspect ratio and element (primitive) aspect ratio are the same and as specified:

g0 =
Graphics[{Opacity[0.5, Red], Rectangle[{0, 0}, {3, 2}]}, AspectRatio -> 2/3,
Background -> GrayLevel[0.8], PlotRangePadding -> 0]

(There is a one pixel discrepancy along the right edge where the background shows through but I believe that is within the margin of error for rasterization in Mathematica. That is to say there are other small discrepancies that would also need to be accounted for before considering this a specific aspect ratio problem.)

g0 // Image // ImageDimensions

{360, 240}

PlotRangePadding is included in the aspect ratio calculation such that the extended plot area has the specified aspect ratio which means that elements have a different aspect ratio unless the padding is such that it exactly matches the aspect ratio.

g1 =
Show[g0, Axes -> True, PlotRangePadding -> {15, 2}, ImagePadding -> 0, ImageMargins -> 0]

The image dimensions are similar to g0 though the Rectangle is clearly distorted.

g1 // Image // ImageDimensions

{360, 240}

If the ratio of the PlotRangePadding matches the numeric AspectRatio the image aspect ratio and the element aspect ratio match:

Show[g0, Axes -> True, PlotRangePadding -> {3, 2}, ImagePadding -> 0, ImageMargins -> 0]

ImagePadding is excluded from the calculation of aspect ratio; it is area added outside the plot area but within the graphic area where e.g. Background applies and where ticks and labels may reside. With PlotRangePadding -> 0 the element aspect ratio is still exactly as specified by AspectRatio.

g2 =
Show[g0, Axes -> True, PlotRangePadding -> 0,
ImagePadding -> {{70, 70}, {20, 8}}, ImageMargins -> 0]

g2 // Image // ImageDimensions

{360, 175}

ImageMargins is excluded from aspect ratio and image size calculations. It extends the image beyond the specified size with a blank area; it may not contain ticks or labels.

g3 =
ImageMargins -> {{30, 30}, {50, 50}}]

The image is larger than the default width-360:

g3 // Image // ImageDimensions

{420, 340}

## ImageSize

When an absolute ImageSize is given that does not match the requested ratio the graphic is scaled down to fit entirely within that size and the image area is extended to match the absolute size. The exception is ImageMargins (g3) which as stated before is excluded from ImageSize; it adds padding outside of that bounding box.

Show[#, ImageSize -> {160, 180}] & /@ {g0, g1, g2, g3}

ImageDimensions /@ Image /@ %

{{160, 180}, {160, 180}, {160, 180}, {220, 280}}

Scaled and ImageScaled coordinates are extremely useful to study the behaviors of the options for Graphics. I'll try to contribute what I can. What follows, mostly applies to Plot and similar functions. Often Graphics created explicitly with the Graphics head, such as those in Mr.Wizard's answer may behave differently, as compared to Plot.

First example:

Plot[Sin[x], {x, 0, 1},
Frame -> True, Background -> LightBlue,
AspectRatio -> 0.5, ImageSize -> {360, 360},
ImagePadding -> 30, PlotRangeClipping -> False,
Epilog -> {Opacity[.2], Yellow,
Rectangle[ImageScaled[{0, 0}],
ImageScaled[{1, 1}]
]
}
]

Show[%, AspectRatio -> 2]

ImageDimensions @ %%
ImageDimensions @ %%

{360, 360}
{360, 360}

Conflicting specifications for ImageSize and AspectRatio lead to a plot, that is as large as possible, while conforming to AspectRatio and not exceeding the ImageSize. I find especially peculiar the fact, that ImageScaled[{0,0}] is at the boundary of the padding of the image, not the lower-left corner of the entire graphic. This is illustrated by the translucent yellow rectangle, which occupies the ImageScaled range from {0,0} to {1,1}, while the light-blue background covers the entire {360, 360} square.

As Alexey pointed out, the accurate description of AspectRatio's behavior is hidden quite deep in the documentation, specifically under the "Properties and Relations" tab.

AspectRatio determines the ratio of PlotRange, not ImageSize.

This is easily tested with the rasterize trick, similar to what Alexey did in the linked question.

g =
Plot[Sin[x], {x, 0, 1},
Frame -> True, Background -> LightBlue,
AspectRatio -> 0.5, ImageSize -> {360, 360},
ImagePadding -> 30, PlotRangeClipping -> False,
Epilog -> {Opacity[.2], Yellow,
Rectangle[ImageScaled[{0, 0}],
ImageScaled[{1, 1}]
],
Green,
Annotation[Rectangle[Scaled[{0, 0}],
Scaled[{1, 1}]
],
"One", "Region"
]
}
]

The green rectangle is annotated and covers the PlotRange, as per definition of Scaled. I use Rasterize to get the coordinate range it occupies in terms of printer points:

Rasterize[g, "Regions"]

{{"One", "Region"} -> {{30., 105.}, {330., 255.}}}

This output means, that the annotated rectangle occupies pixels lying in the range from {30., 105.} to {330., 255.}. These are Real numbers, by the way, not integers. Rasterize in this respect is very accurate and can calculate sizes to three digits past the decimal, unlike, say, ImageDimensions which returns integers. Also, when using this trick for other needs, it's very important to remember, that the coordinates in the rasterized graphics are flipped. x is zero on the left, as usual, but y=0 is located at the top of the image.

Table[#2/#1 & @@ (#2 - #1) & @@
Rasterize[Show[g, AspectRatio -> i], "Regions"][[-1, 2]], {i, .1, 1.9, .1}]

{0.1, 0.2, 0.3, ... , 1.7, 1.8, 1.9}

That much we knew. The plot range or, in other words, the Scaled[{0,0}] to Scaled[{1,1}] ranges conforms to the AspectRatio. Show is convenient in allowing us to override any of the options of g. Therefore we can study effects of altering PlotRangePadding and others:

Table[#2/#1 & @@ (#2 - #1) & @@
Rasterize[Show[g, AspectRatio -> i,
ImagePadding -> {{150, 6}, {100, 20}}],
"Regions"][[-1, 2]], {i, .1, 1.9, .1}]

However, the output remains the same. This can be easily expanded to a Dynamic or Manipulate construct, but I feel that "AspectRatio controls the height-to-width of the PlotRange" is a sufficiently exhaustive description. See my edit regarding PlotRangePadding and it being or not being a part of PlotRange.

EDIT

As Alexey rightly points out, in my answer I am dismissing the subtle difference between PlotRange and PlotRangePadding. AspectRatio, as observed, controls the height-to-width of the sum of PlotRange and PlotRangePadding. Well, allow me to confuse you all further:

Plot[Sin[x], {x, -3, 3}, PlotRange -> {{-2, 2}, {-.9, .9}},
PlotRangeClipping -> False, PlotRangePadding -> .3, Frame -> True,
Epilog -> {Opacity[.2], Yellow,
Rectangle[ImageScaled[{0, 0}], ImageScaled[{1, 1}]], Green,
Annotation[Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]], "One",
"Region"]}]

So how would we like to define things? PlotRangePadding increases the PlotRange and the true-real-full PlotRange is that what is specified plus the padding? Then my definition of the behavior of AspectRatio is ok. But if we're arguing about definitions... Sin[x] is plotted in the x>2 range, so I suppose the regions of -2.3<x<-2 && 2<x<2.3 could be considered part of the plot range which was expanded by the PlotRangePadding option. On the other hand, the curve is not plotted in the -1<y<-.9 && .9<y<1 range, so here PlotRangePadding did not expand the PlotRange.

• Thank you for another great answer but I cannot agree that the statement that Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]] covers the PlotRange is exhaustive: if you add non-zero PlotRangePadding it becomes obvious that Scaled covers also PlotRangePadding. And the exhaustive statement would be that it covers PlotRange with PlotRangePadding added. Similarly I cannot agree that the statement "AspectRatio controls the height-to-width of the PlotRange" is exhaustive because it says nothing about PlotRangePadding. – Alexey Popkov May 19 '15 at 8:02
• Yes, I was reflecting on that just now in a comment on the answer to your previous question. – LLlAMnYP May 19 '15 at 8:09
• In response to the EDIT section: I feel natural to say that PlotRangePadding increases the plot range but not the value of the PlotRange option which remains the same as can be verified by applying Options[#, PlotRange]&. I also have to stress that Plot returns an object with Head Graphics. This object has no "stamp" that it was created by Plot and by essence is the same Graphics that can be constructed by user in many other ways without the built-in plotting functions. – Alexey Popkov May 19 '15 at 8:38
• Yes, in that sense padding increases the range, and then its height-to-width is determined by AspectRatio. An example of different behaviors: g1=Plot[...,PlotRangePadding->Scaled[.1]]; g2=Graphics[{},PlotRangePadding->Scaled[.1]];Options[#,PlotRangePading]&/@{g1,g2} returns {{Scaled[.1],Scaled[.1]},{Scaled[.1],Scaled[.1]}} in the first case and simply Scaled[.1] in the second. – LLlAMnYP May 19 '15 at 9:06
• Functions like Plot and ListPlot usually process their Graphics-related options in some way instead of passing them down to the final Graphics unchanged. They do so even when it is not needed what sometimes results in unexpected behavior or bugs (example). – Alexey Popkov May 19 '15 at 9:20

As it is recently uncovered by Carl Woll, ImageSize accepts undocumented form

ImageSize -> Automatic -> {width, height}

which allows you to specify the width and height of the plot range directly.

This option has higher precedence than AspectRatio:

gr = Graphics[{Lighter@Blue, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
ImageSize -> Automatic -> {300, 100}, AspectRatio -> 1, Frame -> True,
Background -> GrayLevel[0.8], FrameStyle -> Opacity[0]]

ImageCrop[%] // ImageDimensions

{300, 100}

It can be used in combination with AspectRatio:

Graphics[{Lighter@Blue, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
ImageSize -> Automatic -> {Automatic, 100}, AspectRatio -> 1/3, Frame -> True,
Background -> GrayLevel[0.8], FrameStyle -> Opacity[0]]

ImageCrop[%] // ImageDimensions

{300, 100}

The only (but crucial!) drawback is that this undocumented form doesn't play well when Graphics is wrapped by Inset:

Graphics[{Inset[gr, {0, 0}, {0, 0}, Automatic]}, Background -> LightGreen,
ImageSize -> {400, 150}]

A workaround is to wrap Graphics by Pane, Framed, Text or ExpressionCell:

Graphics[{Inset[Text[gr]]}, Background -> LightGreen, AspectRatio -> 1/3]

ImageCrop@ImageCrop@% // ImageDimensions

{300, 100}

Unfortunately with this workaround we loose the ability to position inset relative to the coordinates in the intrinsic coordinate system of its Graphics object as well as relative to Scaled coordinates inside its plotting range. :(


text:
Public Group

# RPG Battle Function

This topic is 2714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello All, I'm new to these forums so I should introduce myself I suppose, my name is Clark and I am 22 years old from Texas, USA. I began seriously programing 2/1/11 *not much experience =p*, I'm focusing on C++ for now with the goals of Freelance Game Development and hopefully an Education/Career in Software Engineering.

On to my Question.

I'm writing a basic Text based RPG to test my knowledge of C++ thus far.
The problem I'm having is now that I have a working battle function created, I'm trying to get it to take on different monsters health, not at the same time, just. Let me type some pseudo code.
Class Monster
int health
Monster.Goblin(20)
Monster.Orc(50)
Monster.Troll(100)

Up till this point I typed out 3 different functions entirely for each monster's battle.
But I'm now learning about pointer's and references and I believe that is the direction I need to go for this.

I desire a function called
Battle()
while (playerhealth > 0 && monsterhealth > 0)
also I need like
monsterhealth = (monsterhealth - pdamage)
etc, where monsterhealth is whichever monster the place choses to battle.

I am NOT asking someone to write this code for me. Please note that.

All I am asking is, do I do this with a pointer? a reference? another variable? or "->" I haven't learned this operator yet but I have seen it used in similar functions on a tutorial website.

##### Share on other sites
Figured I would add code incase anyone wanted it. I just threw this together to experiment with the more integers option.
 cout << "What do you wish to fight?\n\n"; cout << "1. Goblin (Lv. 1)\n"; cout << "2. Orc (Lv. 2)\n"; cout << "3. Troll (Lv. 3)\n"; cin >> choice; switch (choice) { case 1: { Monster goblin("Goblin",20,5,5); goblin.Greet(); mhp = goblin.health; mname = goblin.name; Fight(); break; } case 2: { Monster orc("Orc",50,10,15); orc.Greet(); mhp = orc.health; mname = orc.name; Fight(); break; } case 3: { Monster troll("Troll",100,15,50); troll.Greet(); mhp = troll.health; mname = troll.name; Fight(); break; } } break; } case 2: { cout << "This is town\n\n"; break; } } } void Fight() { // How to get different monsters health here based on what player chose... cout << mname << " has " << mhp << " health.\n"; }

This code works, but is there a better more efficent way? Because as this is going I am ignoring scopes and working with alot of Global ints.

To prevent triple post I'm editing this 15 minutes later to show what I came up with.
 case 1: { Monster goblin("Goblin",20,5,5); goblin.Greet(); Fight(goblin.name, goblin.health); break; } case 2: { Monster orc("Orc",50,10,15); orc.Greet(); Fight(orc.name, orc.health); break; } case 3: { Monster troll("Troll",100,15,50); troll.Greet(); Fight(troll.name, troll.health); break; } } break; } } } void Fight(string mName, int mHealth) { cout << mName << " has " << mHealth << " health.\n"; // using passing variables }
Passing variables into function, I made this work! I believe I answered my own question... sorry forum

##### Share on other sites
Not a bad start for neophyte, actually. There are some simplifications you could make, and learn some new constructs at the same time.

Rather than creating an opponent with all it's parameters and calling the same functions for every case, use the case statement just to select parameters.
 // Pseudo-code switch( user-choice) { case 0: setup-monster0-parameters; break; case 1: setup-monster1-parameters; break; case 2: setup-monster2-parameters; break; } Monster monster( monster-parameters ); monster.Greeting(); Fight();

You could even setup all the info ahead of time.
 struct monsterInfo { string name; int health, armor, ammo; }; monsterInfo info[3]; info[0].name = "orc"; info[0].heath = ...; info[1].name = "something else"; info[1].heath = ...; // additional setups Monster monster; // one monster to re-use in a loop // then bool done = false; while( !done ) { get-user-choice; monster.SetParemeters(info[ user-choice ]); monster.Greeting(); Fight(); done = user-asks-for-another-round; } cout << "Hook 'em Horns!" << endl; // or, alternatively cout << "Go Bucks!" << endl;

Lots of different ways to do it. When you want to get into STL (Standard Template Library), you can use std::vector<monsterInfo> to push_back the preconstructed parameters, as an excercise.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631782
• Total Posts
3002324
×

format: plain


text:
Ask Your Question

# husky melodic does not launch

Hello, I am a bit new to the ROS, but followed some turtlebot3 tutorials. I am using melodic, and want to use Husky robot. I installed all required packages one by one (following the errors, then I made necessary git clone & catkin_make operations; don't know any easier ways), but I still cannot make Husky work. I am following (actually cannot) the steps in that page:

http://wiki.ros.org/husky_gazebo/Tuto...

After I write $roslaunch husky_gazebo husky_empty_world.launch , that's what I get: (Errors are through the end , [ERROR] [1588197605.276042609]: Failed to build tree: child link [base_laser_mount] of joint [laser_mount_joint] not found, Error [parser_urdf.cc:3170] Unable to call parseURDF on robot model, Error [parser.cc:406] parse as old deprecated model file failed. [ERROR] [1588197616.434866, 10.049000]: Spawn service failed. Exiting.) ... logging to /home/herewego/.ros/log/c7b848b6-8a64-11ea-bcde-ac2b6e3c7e2c/roslaunch-hereWeGo-1795.log Checking log directory for disk usage. This may take a while. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. xacro: in-order processing became default in ROS Melodic. You can drop the option. started roslaunch server http://hereWeGo:45533/ SUMMARY ======== PARAMETERS * /ekf_localization/base_link_frame: base_link * /ekf_localization/frequency: 50 * /ekf_localization/imu0: imu/data * /ekf_localization/imu0_config: [False, False, Fa... * /ekf_localization/imu0_differential: True * /ekf_localization/imu0_queue_size: 10 * /ekf_localization/imu0_remove_gravitational_acceleration: True * /ekf_localization/odom0: husky_velocity_co... * /ekf_localization/odom0_config: [False, False, Fa... * /ekf_localization/odom0_differential: False * /ekf_localization/odom0_queue_size: 10 * /ekf_localization/odom_frame: odom * /ekf_localization/two_d_mode: True * /ekf_localization/world_frame: odom * /gazebo/enable_ros_network: True * /husky_joint_publisher/publish_rate: 50 * /husky_joint_publisher/type: joint_state_contr... * /husky_velocity_controller/angular/z/has_acceleration_limits: True * /husky_velocity_controller/angular/z/has_velocity_limits: True * /husky_velocity_controller/angular/z/max_acceleration: 6.0 * /husky_velocity_controller/angular/z/max_velocity: 2.0 * /husky_velocity_controller/base_frame_id: base_link * /husky_velocity_controller/cmd_vel_timeout: 0.25 * /husky_velocity_controller/enable_odom_tf: False * /husky_velocity_controller/estimate_velocity_from_position: False * /husky_velocity_controller/left_wheel: ['front_left_whee... * /husky_velocity_controller/linear/x/has_acceleration_limits: True * /husky_velocity_controller/linear/x/has_velocity_limits: True * /husky_velocity_controller/linear/x/max_acceleration: 3.0 * /husky_velocity_controller/linear/x/max_velocity: 1.0 * /husky_velocity_controller/pose_covariance_diagonal: [0.001, 0.001, 0.... * /husky_velocity_controller/publish_rate: 50 * /husky_velocity_controller/right_wheel: ['front_right_whe... * /husky_velocity_controller/twist_covariance_diagonal: [0.001, 0.001, 0.... * /husky_velocity_controller/type: diff_drive_contro... * /husky_velocity_controller/velocity_rolling_window_size: 2 * /husky_velocity_controller/wheel_radius_multiplier: 1.0 * /husky_velocity_controller/wheel_separation_multiplier: 1.875 * /robot_description: <?xml version="1.... * /rosdistro: melodic * /rosversion: 1.14.5 * /twist_mux/locks: [{'topic': 'e_sto... * /twist_mux/topics: [{'topic': 'joy_t... * /use_sim_time: True NODES / base_controller_spawner (controller_manager/spawner) ekf_localization (robot_localization/ekf_localization_node) gazebo (gazebo_ros/gzserver) gazebo_gui (gazebo_ros/gzclient) robot_state_publisher (robot_state_publisher/robot_state_publisher) spawn_husky_model (gazebo_ros/spawn_model) twist_marker_server (interactive_marker_twist_server/marker_server) twist_mux (twist_mux/twist_mux) auto-starting new master process[master]: started with pid [1809] ROS_MASTER_URI=http://localhost:11311 setting /run_id to c7b848b6-8a64-11ea-bcde-ac2b6e3c7e2c process[rosout-1]: started with pid [1820] started core service [/rosout] process[gazebo-2]: started with pid [1827] process[gazebo_gui-3]: started with pid [1832] process[base_controller_spawner-4]: started with pid [1837] process[ekf_localization-5]: started with pid [1838] process[twist_marker_server-6]: started with pid [1839] process[robot_state_publisher-7]: started with pid [1844] process[twist_mux-8]: started with pid [1850] process[spawn_husky_model-9]: started with pid [1853] [ INFO] [1588197605.269713731]: [twist_marker_server] Initialized. [ERROR] [1588197605.276042609]: Failed to build tree: child link [base_laser_mount] of joint [laser_mount_joint] not found [robot_state_publisher-7] process has died [pid 1844, exit code 1, cmd /opt/ros/melodic/lib/robot_state_publisher/robot_state_publisher __name:=robot_state_publisher __log ... edit retag close merge delete ## 1 Answer Sort by » oldest newest most voted So here's what I've done: I followed the installation steps again: http://wiki.ros.org/Installation/Ubuntu Afterwards, I was able to install husky via apt-get:$ sudo apt-get install ros-melodic-husky-simulator

Then, there was no problem. By the way, instead of sourcing my workspace, I directly used command line to launch Husky, in other words, I wrote

\$ roslaunch husky_gazebo husky_empty_world.launch to the command line. I later removed my workspace, it was messed up.

more

## Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

## Stats

Asked: 2020-04-29 17:08:54 -0500

Seen: 758 times

Last updated: Apr 29 '20