Jump to content

[WIN/MAC/LINUX] KSP Trajectory Optimization Tool v1.6.9 [New MATLAB Version!]


Recommended Posts

Oh, as a heads up, on the wishlist for v0.9 is the following. As with KSP itself, these are subject to change. :)

  • Investigate having the code iterate on departure date to find a date that aligns with your mean anomaly at epoch so that when you compute a departure date and location, your spacecraft will be at that location at that time. (includes input checking on new quantities)
  • Investigate pulling in the body being orbited from the SFS file and potentially updating the body being orbited around. Mostly for flyby and orbit change code.
  • Bug fix the SFS reader.

Other things being investigated for 0.9 or later:

  • Create output files that contain analysis results that can be saved and read in to the various applications.
  • Create printable "reports" that contain the output of each application on one printable page.
  • Remember which folder was last used for selecting an SFS file and make this default.
  • Look for collisions/SOI intersections with unwanted moons on your way out from some body.
  • "Also, a suggestion for an alternative porkchop plot mode - have the y axis be days after departure not the absolute time. (Effectively tilts the graph 45 degrees, assuming a square grid)."

Edited by Arrowstar
Link to comment
Share on other sites

I've yet to provide my save file and get my head around all this, but in terms of intercepting the target planet, is it possible to adjust the intercept point so that your vessel will assume an orbit in the same direction as the planet? Like, if your intercept point is "under" a planet - or on the side closest to the sun, you'll be orbiting in one direct but if you intercept "above" the planet then you'll be orbiting in the opposite direction. OR is that level of accuracy too great for this tool and manual adjustments and eye-balling is going to be required regardless?

Link to comment
Share on other sites

I've yet to provide my save file and get my head around all this, but in terms of intercepting the target planet, is it possible to adjust the intercept point so that your vessel will assume an orbit in the same direction as the planet? Like, if your intercept point is "under" a planet - or on the side closest to the sun, you'll be orbiting in one direct but if you intercept "above" the planet then you'll be orbiting in the opposite direction. OR is that level of accuracy too great for this tool and manual adjustments and eye-balling is going to be required regardless?

Okay. Well, whenever you want to get the save file to me is fine. You could just dump the contents in this thread, using CODE tags to keep it from getting too long if you'd like. I can work with it from there.

As to your question. What you're asking for is essentially impossible, though not because of accuracy. The two body patched-conics assumption assumes that every "local" gravity field (using our Kerbin-Duna trajectory, the gravity fields of Kerbin and Duna) is infinitesimal in size. Because of this, according to the assumption, there is no orbit around Duna. You simply run into the point mass that is the planet.

Now, in practice you're right, we usually target somewhere near the planet to achieve a particular orbit. But to do that, we need the concept of bodies with finite gravity fields, which patched conics lacks. In short, KSP TOT (which is built on patched-conics) can't do what you're asking for because its underlying assumptions do not permit it.

There are two workarounds, however.

1) After you get into the Sun's SOI, feel free to use RCS to adjust your orbit past Duna as you see fit. The corrections will be very small, so use fine controls mode (caps lock I think).

2) Wait until you get into Duna's SOI, then use the Optimal Two Burn Orbit Change Tool (KSP TOT -> Tools menu). Grab your initial orbit from the SFS file using the feature I wrote, and then plunk in your desired orbit. KSP TOT will compute the two burns you need, as well as their locations in the orbits. Execute the plan as KSP TOT as generates it and you'll end up where you want to be.

Option 1 is (marginally) cheaper but harder to execute. Option 2 is a bit more expensive but KSP TOT does the math for you. I prefer using (2) but it's up to you.

Does my explanation make sense? :) Thanks for asking great questions, let me know if I can help with anything else.

Link to comment
Share on other sites

So I started a new persistence (I shan't send you my 'bugged' file) and started from scratch. Everything was easy to understand but I ALMOST gave up with the last bit: adjusting my departure burn +/- a few seconds past peri so that you score an intercept. I didn't realise it was so sensitive and the intercept window is very narrow. I was +/- 10 seconds and clicking like a mad man trying to find an intercept. I nearly gave up and then realised that intercept window is literally 1 second wide and it is very easy to miss if you're a mad man. :huh: Lesson - after the maths bit adjust up to 20 seconds in one second increment each way till you get a hit!

Another lesson - you need to be absolutely certain you are in the correct orbit when burning. In the example above - launch was about an hour before the burn to Duna. It wasn't spelt out but this is the best way to ensure you're in the correct orbit. Get this wrong and your 'time after periapse' won't mean squat because Duna will be in the wrong position when you burn.

Some feedback:

I don't know if its an option for TOT to remember which folder your persistence file is in. It defaults to the folder TOT is in meaning I had to navigate every single time to my D:\Program Files\KSP\saves\default folder. Small thing really - if it just remembered the same folder I used last time then that would have been sweet. :) I'm now considering moving my TOT folder from my desktop into my KSP folder to cut down on some of that navigation.

Another thing is that there is a LOT of information on your windows. When you get bored one day (joke) consider having a 'lite' version and an 'full' version - or a toggle button - that hides all but the essential information. I want to get to Duna so I really only need four things - the delta values and the time from periapses. All the rest is frightening and may actually discourage noobs. Sure, people can just ignore it, but all those hi-tech screenshots might make people go NERD and leave. :(

I like the way the depart/arrive times autofill. The import from sfs is sweet. :)

I've yet to try the more advanced functions but certainly intend to! Especially that two burn thing to get my orbit right.

Oh - and ensure you include your tutorial in the first OP or link to this one here!

Edit: to really push the boundary - you need to determine if other bodies are in the way of a predicted burn. No point working out the perfect flight to Duna if the Mun gets in the way. :)

Edited by togfox
Link to comment
Share on other sites

Not sure. Do you have the Java Runtime Environment installed on your computer?

Ok, it was a JRE Error on my Tablet, but now KSPTOT failes to start and returns:

File: 'bodies.ini' does not exist or can not be opened

Error in => projectMain.m at line 8

Another error occured at a Eve->Duna flyby calculation:

Gel5ZPF.png

And your tool is insane, I got a Eve->Jool flyby with an Eve-Pariapse thats 100m above the atmosphere :0.0:

Link to comment
Share on other sites

Would it be possible to create some sort of save file that KSPTOT could create containing the complete manouvers and stuff, so you calculate a transfer/flyby, save it and be able to open it anytime again without calculating stuff again.

And will there come up the posibility to use the flyby calculator on the Joolian-Moons?

btw, there is a free Eve-return trajectory within the first year, that brings you 700m above the atmosphere of Eve :0.0:

And I finally got a Duna flyby to Jool, it saves about 100 m/s but increases flight time by 500 days :wink: And I fly past duna about 300m above the atmosphere of course :D

Edited by Spanier
Link to comment
Share on other sites

Hi Arrowstar

I'm having strange results on a trip to Eve from Kerbin. The trajectory KSP TOT calculated is way off and I can't figure out why. I do not rule out an entry error on my end of course but I would be glad if anyone could have a look:

YuV6Y3P.png

rhb4lcm.png

bdKbCDH.png

EE72IDw.png

z0PXXgL.png

I did not use MechJeb but the method of entering the result from the Departure Burn Optimizer into the Maneuver Node editor worked perfectly on a previous mission to Eve.

The "select orbit from .sfs file" feature did not work as well in this session. The vessel selection window did not show up, even after several seconds of waiting time.

Edit: I set number of synodic periods to calculate to 3 if that does matter.

Link to comment
Share on other sites

Ok, it was a JRE Error on my Tablet, but now KSPTOT failes to start and returns:

File: 'bodies.ini' does not exist or can not be opened

Error in => projectMain.m at line 8

This shouldn't happen. Can you re-download KSP TOT and try again? bodies.ini is the file that stores information about celestial bodies in KSP. It's packaged with the executable and actually sits right next to it when you run KSP TOT. Something odd is going on. Where did you try to run KSP TOT from? Maybe try somewhere you definitely have write permissions to (My Documents, etc).

Another error occured at a Eve->Duna flyby calculation:

<snip>

And your tool is insane, I got a Eve->Jool flyby with an Eve-Pariapse thats 100m above the atmosphere :0.0:

Bug ID'd and fixed. Fix will show up in v0.9.

And yeah, the flyby constraint for minimum altitude is 100 meters about the atmosphere. It's what I call doing it "Jeb-style." Don't screw up or things are going to get toasty. ;)

Would it be possible to create some sort of save file that KSPTOT could create containing the complete manouvers and stuff, so you calculate a transfer/flyby, save it and be able to open it anytime again without calculating stuff again.

And will there come up the posibility to use the flyby calculator on the Joolian-Moons?

Yeah, I'd like this to be a feature, maybe for whatever comes after 0.9. I've been thinking about implementations for a while now, have some ideas. I may also do the same for the bodies.ini file, so you can export the existing one, edit it as you need to, and reimport it. But I think I'll wait on that one for a bit, since it'll take some extra code to get that to roll. Saving the results of an analysis should be fairly straight-forward though. Of course, reading them back in and processing them won't be, but oh well. :P

And I finally got a Duna flyby to Jool, it saves about 100 m/s but increases flight time by 500 days :wink: And I fly past duna about 300m above the atmosphere of course :D

Can I get the details on that one? Departure date, flyby date, arrival date? I'd like to see it. :) What was the flyby periapsis?

Hi Arrowstar

I'm having strange results on a trip to Eve from Kerbin. The trajectory KSP TOT calculated is way off and I can't figure out why. I do not rule out an entry error on my end of course but I would be glad if anyone could have a look:

<snip snip snip...>

I did not use MechJeb but the method of entering the result from the Departure Burn Optimizer into the Maneuver Node editor worked perfectly on a previous mission to Eve.

I just attempted to recreate the issue you presented, but was unable to. I scheduled my burn to correspond with your departure and arrival days and ended up with this:

Myqpauz.png

I was able to execute this in the game just fine:

DaO4zmJ.png

A few things here:

1) Notice the MechJeb time I'm departing at. 2 Years, 76 Days. This is Year 3, Day 77 in Kerbal Space Program time. KSP Time is what KSP TOT uses. So if you left when the clock said 3 Years, 77 Days in MechJeb, you were one year and one day too late. :)

2) I used a slightly different ejection orbit than you did, but it worked fine. My departure hyperbolic orbit was pretty similar, and my departure orbit plot looked a lot like yours. It could be numerical error on KSP TOT's end, but I don't see most of the signs that normally arise when that happens (wierd plots, orbits with specific parameters, etc).

Please review and let me know what you think. I'd be happy to get to help you get to the bottom of this.

The "select orbit from .sfs file" feature did not work as well in this session. The vessel selection window did not show up, even after several seconds of waiting time.

Edit: I set number of synodic periods to calculate to 3 if that does matter.

In order to debug SFS-related issues, I need the SFS file. Could you please paste the contents of the offending SFS file here (peferably in CODE brackets) so I can troubleshoot? Please make sure the SFS you copy here is still being a problem before you do. :)

Link to comment
Share on other sites

So I started a new persistence (I shan't send you my 'bugged' file) and started from scratch.

Actually, could you? I need something to work with in order to recreate your issue. If I can't recreate it, I can't fix it.

Another lesson - you need to be absolutely certain you are in the correct orbit when burning. In the example above - launch was about an hour before the burn to Duna. It wasn't spelt out but this is the best way to ensure you're in the correct orbit. Get this wrong and your 'time after periapse' won't mean squat because Duna will be in the wrong position when you burn.

Indeed. What do you mean by correct orbit? You mean that you need to leave at the correct time? Or are you referring to your orbit about Kerbin?

I don't know if its an option for TOT to remember which folder your persistence file is in. It defaults to the folder TOT is in meaning I had to navigate every single time to my D:\Program Files\KSP\saves\default folder. Small thing really - if it just remembered the same folder I used last time then that would have been sweet. :) I'm now considering moving my TOT folder from my desktop into my KSP folder to cut down on some of that navigation.

Yeah, this is do-able I think. Marked down for investigation. :)

Another thing is that there is a LOT of information on your windows. When you get bored one day (joke) consider having a 'lite' version and an 'full' version - or a toggle button - that hides all but the essential information. I want to get to Duna so I really only need four things - the delta values and the time from periapses. All the rest is frightening and may actually discourage noobs. Sure, people can just ignore it, but all those hi-tech screenshots might make people go NERD and leave. :(

I'll think about it. KSP TOT is somewhat meant for the more advanced users anyways, but you make an interesting point. I'll consider it but no promises...

I like the way the depart/arrive times autofill. The import from sfs is sweet. :)

Thanks! The best part of writing your own software is that when you just desperately want a feature, you can go write it yourself. Only your imagination and skill stop you. :)

I've yet to try the more advanced functions but certainly intend to! Especially that two burn thing to get my orbit right.

Oh - and ensure you include your tutorial in the first OP or link to this one here!

Edit: to really push the boundary - you need to determine if other bodies are in the way of a predicted burn. No point working out the perfect flight to Duna if the Mun gets in the way. :)

Thanks for the note about the tutorial! I'll do that now. I could maybe write something to check to see if a body is in the way of your departure orbit, but I wouldn't be able to correct for it, so might not be much use. Still an interesting thought, though. I've marked it down on my ideas list. :)

Link to comment
Share on other sites

In order to debug SFS-related issues, I need the SFS file. Could you please paste the contents of the offending SFS file here (peferably in CODE brackets) so I can troubleshoot? Please make sure the SFS you copy here is still being a problem before you do. :)

I posted the content of the persistent.sfs file which I was not able to load into KSP TOT to pastebin since there is a limitation on the amount of characters in a post on this forum: http://pastebin.com/YKW3jC6t

I also tried running KSP TOT with administrator rights to no avail (Windows 7).

A few things here:

1) Notice the MechJeb time I'm departing at. 2 Years, 76 Days. This is Year 3, Day 77 in Kerbal Space Program time. KSP Time is what KSP TOT uses. So if you left when the clock said 3 Years, 77 Days in MechJeb, you were one year and one day too late.

2) I used a slightly different ejection orbit than you did, but it worked fine. My departure hyperbolic orbit was pretty similar, and my departure orbit plot looked a lot like yours. It could be numerical error on KSP TOT's end, but I don't see most of the signs that normally arise when that happens (wierd plots, orbits with specific parameters, etc).

Please review and let me know what you think. I'd be happy to get to help you get to the bottom of this.

I tried it again from scratch with the same result, so I tried it with another ship in another orbit and entered it's orbit parameters into the Departure Burn toll of KSP TOT with the same departure and arrival time from the porkchop plot. When I enter the computed departure burn of this orbit into the maneuver node editor it works as intended.

I think I can rule out any MechJeb time discrepancies because I did not use MechJeb to edit the maneuver node. I did use a maneuver node editor which allows to enter the maneuver time in UT as can be seen in one of my ingame screenshots.

Edit: I played with the UT in the maneuver node editor a bit and noticed that KSP shows an encounter when I enter UT 69678887 instead of the 69677754 calculated by KSP TOT.

Edited by wingnut
Link to comment
Share on other sites

Also, Spanier, just saw your Jool moons flyby question. To do flyby analysis with Jool's moons, set the Central Body in the main KSP TOT window to Jool. Enjoy. :)

Oh, it's just THAT simple, that I didn't thought of that :wink:

And here is my Duna flyby:

nDVSeI1.png

TUrE8y1.png

Note that it's a powered flyby and it took my Computer about 2 hours to calculate :D

Link to comment
Share on other sites

Hmm...

Could you add a way to import the departure / arrival body from a vessel (from sfs)?

Also, a suggestion for an alternative porkchop plot mode - have the y axis be days after departure not the absolute time. (Effectively tilts the graph 45 degrees, assuming a square grid).

And perhaps an option to only allow flybys that don't have any burn?

And perhaps aerobraking on flybys? Or an aerobraking calculator in general?

Finally, a way to import / export a specific transfer.

Edited by The Lone Wolfling
Link to comment
Share on other sites

I posted the content of the persistent.sfs file which I was not able to load into KSP TOT to pastebin since there is a limitation on the amount of characters in a post on this forum: http://pastebin.com/YKW3jC6t

I also tried running KSP TOT with administrator rights to no avail (Windows 7).

Thanks. I found the issue with the SFS file. No idea what's going with the tablet, but since I don't own one myself, I really can't debug. Go digging around your tablet for a file with an extension called "*.ctf". That holds the bodies.ini file, along with other needed files. If you can open the CTF file, you could check to see if the bodies.ini file is in it. But honestly, I'm at a loss.

I tried it again from scratch with the same result, so I tried it with another ship in another orbit and entered it's orbit parameters into the Departure Burn toll of KSP TOT with the same departure and arrival time from the porkchop plot. When I enter the computed departure burn of this orbit into the maneuver node editor it works as intended.

I think I can rule out any MechJeb time discrepancies because I did not use MechJeb to edit the maneuver node. I did use a maneuver node editor which allows to enter the maneuver time in UT as can be seen in one of my ingame screenshots.

Edit: I played with the UT in the maneuver node editor a bit and noticed that KSP shows an encounter when I enter UT 69678887 instead of the 69677754 calculated by KSP TOT.

So the issue is that you can't actually leave when the departure tool says to leave. Here's why:

You're in an orbit, and at a fixed point in time, you are at a known location. Now, KSP TOT gives you both a location in the orbit (the "Departure True Anomaly") and a time (the departure time). However, it may be that your spacecraft will not be at the departure location at the departure time. So you can't just input the departure time into a maneuver node editor, because you might go flying off into a random direction! This is also why moving the maneuver node 1133 seconds (the difference between the two times you gave) probably got you an intercept: you moved to the correct point in the orbit, which is strictly more important than nailing the exact departure time.

Could you add a way to import the departure / arrival body from a vessel (from sfs)?

By this, do you mean setting the departure body in the application you're using to that body specified in the orbit you import from the SFS file?

Also, a suggestion for an alternative porkchop plot mode - have the y axis be days after departure not the absolute time. (Effectively tilts the graph 45 degrees, assuming a square grid).

Not a bad idea, I could certainly do that. I'll make a note to investigate.

And perhaps an option to only allow flybys that don't have any burn?

I discussed this somewhere previously, but basically I can't do this because it restricts the solution space too much (meaning the solver will never converge). It's also not a good idea: sometimes a powered flyby is the cheaper option as compared to a powerless flyby that requires a more difficult departure or arrival (or both).

And perhaps aerobraking on flybys? Or an aerobraking calculator in general?

Also impossible. My code assumes two body motion. To deal with the atmosphere, I'd need an orbit propagator, and those are annoying because you get rid of the analytical solution that makes TOT (relatively) fast.

Finally, a way to import / export a specific transfer

Yep, I'd like to do something like this. :)

Link to comment
Share on other sites

Thanks. I found the issue with the SFS file. No idea what's going with the tablet, but since I don't own one myself, I really can't debug. Go digging around your tablet for a file with an extension called "*.ctf". That holds the bodies.ini file, along with other needed files. If you can open the CTF file, you could check to see if the bodies.ini file is in it. But honestly, I'm at a loss.

I found a file "MATLAB\MATLAB Compiler Runtime\v81\bin\win32\mps_check.ctf" which does not contain a bodies.ini file as far as I can tell. I'm not sure what you meant with "tablet"...

So the issue is that you can't actually leave when the departure tool says to leave. Here's why:

That makes sense and is obvious actually. I should have noticed this myself. Thank you for your explanation and sorry for the inconvenience.

Link to comment
Share on other sites

By this, do you mean setting the departure body in the application you're using to that body specified in the orbit you import from the SFS file?

...sometimes? I'll give two examples:

I hit import from SFS on a vessel in orbit around Kerbin. It sets departure body to Kerbin.

I hit import from SFS on a vessel in orbit around the Sun. It sets departure body to the vessel itself.

I discussed this somewhere previously, but basically I can't do this because it restricts the solution space too much (meaning the solver will never converge). It's also not a good idea: sometimes a powered flyby is the cheaper option as compared to a powerless flyby that requires a more difficult departure or arrival (or both).

Drat.

Also, that's odd. I would have thought that restricting the solution space would improve the solver.

Powered flybys are good, but mean that you have to be in control of the spacecraft while whipping relatively close to a planet. With RemoteTech, that's non-trivial.

Link to comment
Share on other sites

I found a file "MATLAB\MATLAB Compiler Runtime\v81\bin\win32\mps_check.ctf" which does not contain a bodies.ini file as far as I can tell. I'm not sure what you meant with "tablet"...

Okay, no worries. And it was Spanier who had the tablet problem, sorry about that. Getting you all mixed up now. :)

...sometimes? I'll give two examples:

I hit import from SFS on a vessel in orbit around Kerbin. It sets departure body to Kerbin.

I hit import from SFS on a vessel in orbit around the Sun. It sets departure body to the vessel itself.

Right now, setting the departure body to the vessel itself isn't possible. It will be on day, but the functionality is still coming. :) I like the example, though, I'll keep it in mind.

Drat.

Also, that's odd. I would have thought that restricting the solution space would improve the solver.

Powered flybys are good, but mean that you have to be in control of the spacecraft while whipping relatively close to a planet. With RemoteTech, that's non-trivial.

Reducing the solution space is done by setting constrains. All solvers attempt to find a feasible solution (that is, one where the constraints are not violated). If you make too much of the design space infeasible, the solver will never converge. This leads to Bad Things .

Link to comment
Share on other sites

So I said I would upload my persistent - then said I wouldn't - and now I have.

https://dl.dropboxusercontent.com/u/80858415/FoxPersistent.sfs

You'll soon find its in year 10 (year 9 for MJ) and I wonder if this is a factor. Perhaps not - a manually entered year 10 works fine. I was trying to get to Duna and Eve but I didn't get to the "select craft" stage. If you choose to load it in game you'll need Kethane (whatever latest is) and MechJeb (2.0.8).

Kill the ding of doom! ;)

Link to comment
Share on other sites

Reducing the solution space is done by setting constrains. All solvers attempt to find a feasible solution (that is, one where the constraints are not violated). If you make too much of the design space infeasible, the solver will never converge. This leads to Bad Things .

Oh.

I was under the impression that something like that would reduce the dimensionality of the design space, not just the feasible chunk of the design space. In this case reducing the problem from 8 dimensions to 4. (time + magnitude of burn in axises for both initial and flyby burns to just initial burn).

If it's just adding constraints to the design space then of course it's going to be difficult to get a result.

Link to comment
Share on other sites

So I said I would upload my persistent - then said I wouldn't - and now I have.

https://dl.dropboxusercontent.com/u/80858415/FoxPersistent.sfs

You'll soon find its in year 10 (year 9 for MJ) and I wonder if this is a factor. Perhaps not - a manually entered year 10 works fine. I was trying to get to Duna and Eve but I didn't get to the "select craft" stage. If you choose to load it in game you'll need Kethane (whatever latest is) and MechJeb (2.0.8).

Kill the ding of doom! ;)

I had no problems loading it up, so my previous fix that is coming for v0.9 must have done. Mystery solved and Ding of Doom dead. :)

Link to comment
Share on other sites

Oh.

I was under the impression that something like that would reduce the dimensionality of the design space, not just the feasible chunk of the design space. In this case reducing the problem from 8 dimensions to 4. (time + magnitude of burn in axises for both initial and flyby burns to just initial burn).

If it's just adding constraints to the design space then of course it's going to be difficult to get a result.

Ah yeah, the only design variables are the time of departure, TOF to flyby body, and TOF to arrival body. Everything else is just a constraint. :)

Link to comment
Share on other sites

Hey guys, just a heads up. I'll be pretty much off the forums for the next week or so on vacation. The v0.9 update is still coming, but I've been running into some minor problems with the math and it's taking a bit. When I come back I'll try to get things pushed out. Hopefully 0.21 lands by then and we can all stop drooling over the videos and pictures we're seeing. :)

Link to comment
Share on other sites

This program is awesome, and you should feel awesome for writing it!

*Especially* that you allow reading state-files instead of requiring us to figure out and manually input all the parameters.

Though, what I don't understand is how a 100km orbit (circular) has an SMA of 400. Shouldn't it be 200? If I enter 200 the tool behaves as if I was inside Kerbin instead of around it. Doubling that to 400 draws the orbit as I would expect to see in-game while at 100km apo/peri.

Link to comment
Share on other sites

Though, what I don't understand is how a 100km orbit (circular) has an SMA of 400. Shouldn't it be 200? If I enter 200 the tool behaves as if I was inside Kerbin instead of around it. Doubling that to 400 draws the orbit as I would expect to see in-game while at 100km apo/peri.

You're forgetting about the radius of Kerbin itself.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...