I started out in this hobby almost exactly the same way, as a programmer who wanted to get into flight code for multicopters and autonomous planes. And while I've yet to launch a fully autonomous aircraft with my own code at the proverbial stick, within my year or so researching the topic hands-on, I have accumulated some useful knowledge which I'm going to share here.
First, you'll probably need to become intimately familiar with all the hardware that comprises a drone.
If you want to do anything seriously interesting with it, anyway.
There do exist some integrated programmable drones that abstract the hardware part away and let you code basic flight routes, but they're limited by that same abstraction to the most basic maneuvering. This, as many consumer drone owners can attest, is rather boring unless you have a specific application in mind. And specific applications (apart from filming/photography, which are usually automated enough in commercial camera drones out of the box anyway) usually require something more than just a drone with a camera.
Of course, you might be content with that. You might want to simply play with it in your living room or backyard, which is perfectly fine, and in this case a prefab proprietary drone like the Tello might suit you well, especially if you're only going to use it as a stepping stone/demo version before diving into the "real thing" (or not). As a disclaimer, I haven't researched this one in particular, but I'd bet it has all the characteristics of a proprietary product: highly refined, but also sealed, with its own API/ecosystem, and capable of some particular subset of possible flight modes that the developers thought safe/proper. Which is okay if you're using this as a tool for learning programming and/or general robotics, but this will slow one down once one starts to get into anything advanced. Besides, if you decide to move on from one of these to something else, you won't be able to take any of your code along: it will certainly be incompatible with anything not of that manufacturer.
The alternative is to roll your own: buy all the components either separately or as a kit and build a drone for yourself (or buy a prebuilt kit, which is very distinct from buying a commercially manufactured drone). This has all the characteristic advantages and drawbacks of open source: On the plus side, it's highly customizable and extendable, often has the most cutting edge tech, open standards, portability of code, etc. Most importantly for this application, it allows interoperability with about any kind of peripheral you can think of (provided that this peripheral can talk via one of the standard protocols, e.g. SPI/I²C/RS232/OneWire/etc, though you probably could hack in support for proprietary protocols as well if you really wanted). All of that is balanced by around zero customer support: No one's there to hold your hand, and any issues you might experience you'll have to troubleshoot on your own, maybe with the help of knowledgeable friends... or internet strangers like ourselves. Given that you're already a software engineer, you're probably doing it all the time anyway, however.
Second: There's only a few scriptable autopilots.
I'm going to cover the open source ones for the most part, as for the reasons outlined above I was never particularly interested in the proprietary variety. Also, I'm talking about high-level flight code, e.g. code that defines complex behavior on top of some other flight control software, which in turn provides at least basic stabilization and primitive maneuvering. If you want to dabble in low-level stabilization code that works directly with bare metal, you can just fork any flight control project or even write your own.
So, a rundown of all the options in order of increasing complexity:
- Most flight control software has varying degrees of inbuilt flight behavior automation such as takeoff, landing, position hold/loiter, return to home, and waypoint missions.
- The latter represents the most basic form of programming: you set up a flight route consisting of waypoints, possibly with other modes thrown in (e.g. takeoff, go to waypoint A, then B, loiter there for 10 minutes, go home, land). This mission is then uploaded to the drone and off it goes. This, as far as I know, does not support conditionals or other control structures, so is not turing-complete.
For more complex high-level flight control, there's a widely-supported protocol called MAVLink. It allows for a device external to the flight controller to query flight parameters and issue commands via a UART connection. This is the protocol that's usually used by ground station software (through which you define the waypoint missions mentioned above and otherwise remotely control your craft's behavior).
MAVLink is supported by most flight control software suites, and is very bulletproof by the standards of this currently highly experimental field. The data and commands available via the protocol range from the highest inbuilt abstraction level (e.g. add waypoints or change flight modes and set their parameters) to almost the lowest (e.g. query exact attitude, read data from gyros or other peripherals, set rotation rates), and the set can be extended arbitrarily. The only caveat is that it's only a communication protocol/API, so you'll need some kind of external computing device, either onboard or remote, to provide the actual logic.
This "physically external logic" approach is probably the most approachable option for a regular programmer, since you can run your flight code on your laptop in any language you like, controlling the craft remotely via a telemetry link (which is basically a pair of transponders, one of which plugs into USB and the other into the flight controller's UART, providing a bidirectional serial connection over radio). If you do so, mind the latency and link health: it might restrict you to higher-level control. If you find yourself needing more fine-grained control, you can move the code to an onboard computer (e.g. raspberry pi) connected to the flight controller directly, getting rid of the radio link and retaining the familiar Unix-y operating environment.
The MSP protocol mentioned in the other reply falls, as far as I can tell, into the same category, but is somewhat more specific. That's perfectly fine, though; use whatever works for you.
- Finally, there's the option of onboard scripting, defined as user code that runs on the flight controller hardware together with (or, rather, on top of) the basic flight control software itself, and makes use of the latter's capabilities. This allows one to code custom flight logic without modifying the code of the autopilot itself, yet have both high-level control of the autopilot's automation features, and fine-grained low-level access to the craft's hardware with about the lowest possible latency. The approach comes with some operating restrictions, however, since you'll have to work within a real-time operating environment and with very limited resources. Also, there's only a small selection of autopilots which support such scripting, at least ones that I know of, and all of those are thanks to a question I asked earlier on this very site. Here's a summary of the contents:
- Ardupilot supports onboard Lua scripting in its Copter/Rover variants since v4.0 and in Plane since v3.11. As of right now, this seems the most "lightweight-yet-powerful" option and thus most promising for my use case.
- ROSflight has been suggested, which is an autopilot package running on top of the Robot Operating System, all of which is apparently highly modular and allows you to add (or replace) any part of the flight code independently. See the relevant answer for more details.
- Finally, this comment by Kenn Sebesta: Tau Labs supports picoC and full flight scripting. It is very stable and the feature set is robust, but it's a bit abandonware at this point so you'd be on your own for support.
- There might be more I don't know of, so may want to look around some more if you want onboard scripting.
Third: Your hardware choice will depend heavily on which of the above you choose.
The first (implicit) choice is the type of platform: plane, multicopter, boat, car, etc. Of which you seem to have already chosen the second, but I'm going to point out the existence of that choice anyway.
Then comes the flight control system's architecture as outlined above: Is it going to be just a single (scriptable) flight controller? An FC with a control link to a ground station? An FC/onboard general-purpose single board computer pairing? Something else? If you've got a specific application in mind, do you need any particular onboard peripherals/payload that need to be integrated into the control stack?
With all of that in mind, you'll choose a combination of flight controller (hardware) and flight control package (firmware), plus possibly the aforementioned peripherals, secondary computer, radio links for the ground station, etc., and then an airframe that will carry your hardware and payload comfortably.
It's possible you'll find an integrated package with all of that included that will fit your needs, either proprietary or open source hardware. Of the former, the Tello might be one. Of the latter, I know of ArduBee, a single-board copter (in which the PCB is the drone's frame) built for ArduPilot, and MicroHawk, which is purpose-built to fit a Raspberry Pi Zero.
Finally: You'll need to learn to fly the thing manually. No excuses.
No matter what, accidents with UAVs happen. Software bugs or other malfunctions that are capable of leading to an accident are even more common. Especially when it's your own prototype code. It's not a question of if, but when. And just losing the aircraft is one of the better outcomes. A multicopter is inherently dangerous. It's a flying blender with sharp blades connected to a half-kilo brick, which is often traveling at 50+ km/h. You do not want it to fly into anything that you care about. So unless you're only going to fly in a very unpopulated area and run a hundred meters away from the thing before each launch, you must at least learn the basics of flying a drone, in both stabilized (attitude) and acro (rate) modes, to the point of being confident enough in your abilities to assume manual control at any moment if the aircraft starts to act in a way it's not supposed to, and guide it safely to the ground.
Besides, manual piloting of both quadcopters and fixed-wing planes is fun!
Feel free to ask for any clarification or additional details I might have missed, and I'll add it to the answer (or as a comment).