diff --git a/content/drone-stuff/_index.md b/content/drone-stuff/_index.md index 3efa13a..b69ca07 100644 --- a/content/drone-stuff/_index.md +++ b/content/drone-stuff/_index.md @@ -18,3 +18,4 @@ Click on a link in the list below to go to that page: 1. [Omnibus F4 V3 pinout](../../drone-stuff/omnibus-f4-v3-pinout) 1. [Omnibus F4 pro servo diode](../../drone-stuff/omnibus-f4-pro-servo-diode) 1. [Transmitter external module pinout](../../drone-stuff/transmitter-external-module-pinout) +1. [Transportable C1 Chaser](../../drone-stuff/transportable-c1-chaser) diff --git a/content/drone-stuff/getting-uninverted-sbus-smartport-on-the-frsky-xsr-receiver.md b/content/drone-stuff/getting-uninverted-sbus-smartport-on-the-frsky-xsr-receiver.md index 2b37a4d..46a6d35 100644 --- a/content/drone-stuff/getting-uninverted-sbus-smartport-on-the-frsky-xsr-receiver.md +++ b/content/drone-stuff/getting-uninverted-sbus-smartport-on-the-frsky-xsr-receiver.md @@ -7,11 +7,11 @@ insert_anchor_links = "right" To get uninverted SBUS/SmartPort on the FrSky XSR/X4RS receiver, you can repurpose the CPPM pad. Remove the two small resistors shown in the image, and solder the two lower pads (together) to either the CPPM pad or the MOSFET pin shown in the photo: -[![xsr-sbus.jpeg](../../resources/f86da9a7aac1413ebd77825897164f7f.jpeg)](../../resources/f86da9a7aac1413ebd77825897164f7f.jpeg) +[![xsr-sbus.jpeg](../../resources/f86da9a7aac1413ebd77825897164f7f.jpg)](../../resources/f86da9a7aac1413ebd77825897164f7f.jpg) They should be soldered like this (remember to solder both resistor pads together): -[![xsr-sbus2.jpeg](../../resources/815576429ece43789dbc70dfd33517a1.jpeg)](../../resources/815576429ece43789dbc70dfd33517a1.jpeg) +[![xsr-sbus2.jpeg](../../resources/815576429ece43789dbc70dfd33517a1.jpg)](../../resources/815576429ece43789dbc70dfd33517a1.jpg) Now the CPPM pad will be uninverted SBUS/SmartPort instead. It seems to be a bit of a gamble whether you get SBUS or SmartPort, it might be firmware-dependent. diff --git a/content/drone-stuff/transmitter-external-module-pinout.md b/content/drone-stuff/transmitter-external-module-pinout.md index fd6cc5c..b26234a 100644 --- a/content/drone-stuff/transmitter-external-module-pinout.md +++ b/content/drone-stuff/transmitter-external-module-pinout.md @@ -14,7 +14,7 @@ The transmitter (Taranis, Jumper, RadioMaster, etc) pinout is, from top to botto It's illustrated in this photo: -[![pinout.jpeg](../../resources/72d23239af1541d4b170271c1e9e21eb.jpeg)](../../resources/72d23239af1541d4b170271c1e9e21eb.jpeg) +[![pinout.jpeg](../../resources/72d23239af1541d4b170271c1e9e21eb.jpg)](../../resources/72d23239af1541d4b170271c1e9e21eb.jpg) diff --git a/content/drone-stuff/transportable-c1-chaser.md b/content/drone-stuff/transportable-c1-chaser.md new file mode 100644 index 0000000..07cc649 --- /dev/null +++ b/content/drone-stuff/transportable-c1-chaser.md @@ -0,0 +1,45 @@ ++++ +title = "Transportable C1 Chaser" +weight = 11 +sort_by = "weight" +insert_anchor_links = "right" ++++ +I have a [C1 Chaser](https://www.banggood.com/C1-Chaser-1200mm-Wingspan-EPO-Flying-Wing-FPV-Racer-Aircraft-RC-Airplane-KIT-p-1102080.html?custlinkid=667416&p=6W16207412782201611V), and it's a fantastic wing. +It flies great, and is very efficient. The only problem I had with it was that it's too long to easily carry around, as it has a 1.2m wingspan. + +I thought that a C1 Chaser that can break apart for easy transport would be the ideal long-range wing, so I bought a second one and made some modifications to it. +I'm listing the modifications here so you can do the same if you want to. + + +## Spar + +The biggest issue is making the spar removable. +The best way I've found to do that is to use IKEA drinking straws, they have an internal diameter of around 7.5mm, making them ideal for putting the spar through. + +I've cut three straws to length and glued them in the spar channel, as you can see here: + +[![](../../resources/5ac6bff04962497083b8403ed0fded98.jpg)](../../resources/5ac6bff04962497083b8403ed0fded98.jpg) + + +[![](../../resources/65ff483180ad483795b32d0b65f72613.jpg)](../../resources/65ff483180ad483795b32d0b65f72613.jpg) + +For glue, I use [E6000](https://www.banggood.com/ZHANLIDA-152550ml-E6000-B6000-Adhesive-Transparent-Glue-for-RC-Models-p-1604315.html?cur_warehouse=CN&ID=62834216283418&rmmds=search&custlinkid=667416&p=6W16207412782201611V) (sold as Goop in the US) for pretty much everything, but for this one you can use your favorite glue that you know won't dissolve EPO. + + +## Wings + +TODO: I haven't really gotten there yet. + + +## Vertical stabilizers + +The last part is securing the vertical stabilizers. I did this with two very small 3D printed pieces, I slot the stabilizers horizontally (on the left/right axis) onto the fuselage and then connect the wings, which keeps the stabilizers securely in place. + +TODO: I'll add more photos here when this is glued and finalized. + +* * * + +

+Last updated on January 31, 2021. For any questions/feedback, +email me at hi@stavros.io. +

diff --git a/content/model-build-notes/build-notes-for-the-ft-mighty-mini-arrow.md b/content/model-build-notes/build-notes-for-the-ft-mighty-mini-arrow.md index 88009f9..5b061ce 100644 --- a/content/model-build-notes/build-notes-for-the-ft-mighty-mini-arrow.md +++ b/content/model-build-notes/build-notes-for-the-ft-mighty-mini-arrow.md @@ -6,7 +6,7 @@ insert_anchor_links = "right" +++ These notes are a condensed version of the [FT Arrow build video](https://www.youtube.com/watch?v=cD2Ca2oskVs). -![maxresdefault.jpeg](../../resources/d4819ca1c3d0490daaa12f62af09aa00.jpeg) +![maxresdefault.jpeg](../../resources/d4819ca1c3d0490daaa12f62af09aa00.jpg) ## Wings diff --git a/joplinexport.py b/joplinexport.py index 6d65cae..c2fc429 100755 --- a/joplinexport.py +++ b/joplinexport.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +import dataclasses +import mimetypes import re import sqlite3 from collections import defaultdict @@ -6,7 +8,10 @@ from datetime import datetime from pathlib import Path from shutil import copy from shutil import rmtree +from typing import Dict +from typing import List from typing import Optional +from typing import Set def contains_word(word: str, text: str) -> bool: @@ -23,32 +28,39 @@ def slugify(text): return re.sub(r"[\W_]+", "-", text.lower()).strip("-") +@dataclasses.dataclass class Note: """A helper type for a note.""" - def __init__( - self, - id, - parent_id, - parent_title, - title, - body, - updated_time, - tags=[], - ): - self.id = id - self.parent_id = parent_id - self.parent_title = parent_title - self.title = title - self.body = body - self.updated_time = datetime.fromtimestamp(updated_time) - self.tags = tags + id: str + parent_id: str + parent_title: str + title: str + body: str + updated_time: datetime + tags: List[str] = dataclasses.field(default_factory=list) def get_url(self): """Return the note's relative URL.""" return slugify(self.parent_title) + "/" + slugify(self.title) +@dataclasses.dataclass +class Resource: + """A helper type for a resource.""" + + title: str + # The actual extension that the file stored in Joplin has. + extension: str + mimetype: str + + @property + def derived_ext(self): + """Return an extension derived from the resource's mime type.""" + ext = mimetypes.guess_extension(self.mimetype, strict=False) + return "" if ext is None else ext + + class JoplinExporter: """The main exporter class.""" @@ -57,9 +69,8 @@ class JoplinExporter: joplin_dir = Path.home() / ".config/joplin-desktop" def __init__(self): - # A dict of {resource_id: (title, extension)}. - self.resources = {} - self.used_resources = set() + self.resources: Dict[str, Resource] = {} + self.used_resources: Set[str] = set() def clean_content_dir(self): """Reset the content directory to a known state to begin.""" @@ -99,16 +110,15 @@ class JoplinExporter: # Add the resource to the set of used resources, so we can only copy # the resources that are used. self.used_resources.add(resource_id) - return "resources/" + resource_id + "." + resource[1] + return "resources/" + resource_id + resource.derived_ext def copy_resources(self): """Copy all the used resources to the output directory.""" for resource_id in self.used_resources: resource = self.resources[resource_id] - title, extension = resource copy( - self.joplin_dir / "resources" / (f"{resource_id}.{extension}"), - self.static_dir, + self.joplin_dir / "resources" / (f"{resource_id}.{resource.extension}"), + self.static_dir / f"{resource_id}{resource.derived_ext}", ) def read_data(self): @@ -128,8 +138,16 @@ class JoplinExporter: for note_id, tag_id in c.fetchall(): note_tags[note_id].append(tags[tag_id]) - c.execute("""SELECT id, title, file_extension FROM resources;""") - self.resources = {id: (title, ext) for id, title, ext in c.fetchall()} + c.execute("""SELECT id, title, mime, file_extension FROM resources;""") + + self.resources = { + id: Resource( + title=title, + extension=ext, + mimetype=mime, + ) + for id, title, mime, ext in c.fetchall() + } c.execute("""SELECT id, parent_id, title, body, updated_time FROM notes;""") self.notes = defaultdict(list) @@ -141,7 +159,7 @@ class JoplinExporter: self.folders[parent_id], title, body, - updated_time / 1000, + datetime.fromtimestamp(updated_time / 1000), tags=note_tags[id], ) self.notes[note.parent_id].append(note) diff --git a/static/resources/5ac6bff04962497083b8403ed0fded98.jpg b/static/resources/5ac6bff04962497083b8403ed0fded98.jpg new file mode 100644 index 0000000..676d161 Binary files /dev/null and b/static/resources/5ac6bff04962497083b8403ed0fded98.jpg differ diff --git a/static/resources/65ff483180ad483795b32d0b65f72613.jpg b/static/resources/65ff483180ad483795b32d0b65f72613.jpg new file mode 100644 index 0000000..279a1ae Binary files /dev/null and b/static/resources/65ff483180ad483795b32d0b65f72613.jpg differ diff --git a/static/resources/72d23239af1541d4b170271c1e9e21eb.jpeg b/static/resources/72d23239af1541d4b170271c1e9e21eb.jpg similarity index 100% rename from static/resources/72d23239af1541d4b170271c1e9e21eb.jpeg rename to static/resources/72d23239af1541d4b170271c1e9e21eb.jpg diff --git a/static/resources/815576429ece43789dbc70dfd33517a1.jpeg b/static/resources/815576429ece43789dbc70dfd33517a1.jpg similarity index 100% rename from static/resources/815576429ece43789dbc70dfd33517a1.jpeg rename to static/resources/815576429ece43789dbc70dfd33517a1.jpg diff --git a/static/resources/d4819ca1c3d0490daaa12f62af09aa00.jpeg b/static/resources/d4819ca1c3d0490daaa12f62af09aa00.jpg similarity index 100% rename from static/resources/d4819ca1c3d0490daaa12f62af09aa00.jpeg rename to static/resources/d4819ca1c3d0490daaa12f62af09aa00.jpg diff --git a/static/resources/f86da9a7aac1413ebd77825897164f7f.jpeg b/static/resources/f86da9a7aac1413ebd77825897164f7f.jpg similarity index 100% rename from static/resources/f86da9a7aac1413ebd77825897164f7f.jpeg rename to static/resources/f86da9a7aac1413ebd77825897164f7f.jpg