{
  "version": 3,
  "sources": ["ssg:https://framerusercontent.com/modules/m87Fokzr3IYtnTKz2ydB/4lLVOUwHFg8X1EmJj7Tk/ku4Vf4CtH-5.js"],
  "sourcesContent": ["import{jsx as e,jsxs as t}from\"react/jsx-runtime\";import{ComponentPresetsConsumer as n,Link as o}from\"framer\";import{motion as a}from\"framer-motion\";import*as i from\"react\";import{Youtube as r}from\"https://framerusercontent.com/modules/NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js\";import s from\"https://framerusercontent.com/modules/pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js\";export const richText=/*#__PURE__*/t(i.Fragment,{children:[/*#__PURE__*/e(\"p\",{children:\"Language learning has always been a challenge, and books and gamified apps can only get you so far. At some point you\u2019re going to need to have a conversation. Speaking the language with native speakers gives one a leg up in becoming fluent, but not everyone has one of those lying around or can afford to hire one.\"}),/*#__PURE__*/e(\"p\",{children:\"In this month\u2019s OpenAI Application Explorers Meetup, Godfrey Nolan, President, RIIS LLC. demonstrated how you could utilize OpenAI\u2019s Whisper and Gradio to build a role-playing language learning application. Short of hiring your own theater troop, it\u2019s probably the best low stakes emulation of the real-world conversations you will need to practice to gain fluency.\"}),/*#__PURE__*/e(\"p\",{children:\"You can follow along with the video or read the tutorial below, and you\u2019ll be one step closer to your dream of language fluency.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{\"--aspect-ratio\":\"560 / 315\",aspectRatio:\"560 / 315\",height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js:Youtube\",children:t=>/*#__PURE__*/e(r,{...t,play:\"Off\",shouldMute:!0,thumbnail:\"Medium Quality\",url:'<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/hQVJAvJYJmY?si=M7Q3XTe8pV8lWzYo\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen></iframe>'})})}),/*#__PURE__*/e(\"h2\",{children:\"Introducing OpenAI\u2019s Whisper\"}),/*#__PURE__*/e(\"p\",{children:\"Whisper, part of OpenAI\u2019s suite of tools, is a powerful speech recognition engine that performs speech recognition, translation, and language identification. It can transcribe audio files and generate text in multiple languages. This technology forms the backbone of the app we\u2019ll be building today.\"}),/*#__PURE__*/e(\"h2\",{children:\"Understanding Whisper\u2019s Capabilities\"}),/*#__PURE__*/e(\"p\",{children:\"Whisper offers several key functionalities:\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Transcription: Whisper can convert speech to text accurately.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Translation: It can translate audio from one language to another.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Text-to-Speech: Whisper can generate spoken audio from text input.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Multiple Language Support: It supports dozens of languages, from Afrikaans to Vietnamese.\"})})]}),/*#__PURE__*/e(\"h3\",{children:\"Transcription\"}),/*#__PURE__*/e(\"p\",{children:\"Here\u2019s a basic example of using Whisper for transcription:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"import openai\\nopenai.api_key = config.OPENAI_API_KEY\\n\\nmedia_file_path = 'SteveJobsSpeech_64kb.mp3'\\nmedia_file = open(media_file_path, 'rb')\\n\\ndef transcribe_audio(audio_file):\\n    with open(audio_file, \\\"rb\\\") as file:\\n        transcription = openai.audio.transcriptions.create(\\n            model=\\\"whisper-1\\\",\\n            file=file        )\\n    return transcription.text\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"This function takes an audio file as input and returns the transcribed text using Whisper\u2019s transcription capabilities. It uses a file of a famous Steve Job\u2019s speech. If you were to run it, you\u2019d get something like this:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"271\",src:\"https://framerusercontent.com/images/p9KBl4V0D8ZAG3oAaqG4YOMrJTc.png\",srcSet:\"https://framerusercontent.com/images/p9KBl4V0D8ZAG3oAaqG4YOMrJTc.png?scale-down-to=512 512w,https://framerusercontent.com/images/p9KBl4V0D8ZAG3oAaqG4YOMrJTc.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/p9KBl4V0D8ZAG3oAaqG4YOMrJTc.png 1800w\",style:{aspectRatio:\"1800 / 542\"},width:\"900\"}),/*#__PURE__*/e(\"h3\",{children:\"Text-to-Speech\"}),/*#__PURE__*/e(\"p\",{children:\"Whisper also provides text-to-speech functionality:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'from openai import OpenAI\\n\\ncleint = OpenAI()\\n\\nspeech_file = \\'french.mp3\\'\\n\\nresponse = openai.audio.speech.create(\\n    model=\"tts-1\",\\n    voice=\"nova\",\\n    input=\"Le rapide renard brun sauta par dessus le chien parresseux\"\\n)\\n\\nresponse.stream_to_file(speech_file)',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"This function generates an audio file of the input text being spoken.\"}),/*#__PURE__*/e(\"h3\",{children:\"Translation\"}),/*#__PURE__*/e(\"p\",{children:\"The final key to the puzzle is Whisper\u2019s translation functionality.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"from openai import OpenAI\\n\\nclient = OpenAI()\\n\\nfrench_file = open('./french.mp3', 'rb')\\n\\nresponse = client.audio.transaltions.create(\\n    model=\\\"whisper-1\\\",\\n    file=french_file\\n)\\n\\nprint(response.text)\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"The resulting response of this should be \u201CThe quick brown fox jumped over the lazy dog.\u201D\"}),/*#__PURE__*/e(\"h2\",{children:\"Building a Language Learning System\"}),/*#__PURE__*/e(\"p\",{children:\"By combining ChatGPT\u2019s conversational abilities with Whisper\u2019s speech recognition and synthesis capabilities, we can create a powerful language learning tool. The basic flow of such a system would be:\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"The learner speaks a phrase in their target language.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Whisper transcribes and translates this input to English.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"ChatGPT generates an appropriate response based on the context.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"The response is translated back to the target language.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Whisper converts this text response to speech, which is played back to the learner.\"})})]}),/*#__PURE__*/e(\"h2\",{children:\"Implementing the System\"}),/*#__PURE__*/e(\"p\",{children:\"To implement this system, we\u2019ll use Gradio, a Python library for creating simple web interfaces for machine learning models. As you can see here, the interface is quite svelte for such an easy-to-implement framework.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"274\",src:\"https://framerusercontent.com/images/OWejDS7fido1zOn4wrHUTd5c.png\",srcSet:\"https://framerusercontent.com/images/OWejDS7fido1zOn4wrHUTd5c.png?scale-down-to=512 512w,https://framerusercontent.com/images/OWejDS7fido1zOn4wrHUTd5c.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/OWejDS7fido1zOn4wrHUTd5c.png 1976w\",style:{aspectRatio:\"1976 / 548\"},width:\"988\"}),/*#__PURE__*/e(\"p\",{children:\"If you haven\u2019t already use a pip command to install Gradio.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"pip install gradio\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Also, let\u2019s intall PyAudio, which if you can\u2019t already tell by the name will be pretty helpful.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"pip install PyAudio\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Create a file and name it app.py. Then import the following at the top:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"import openai\\nimport config\\nimport pyaudio\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"The next thing we are going to do is create a msgs list variable. We are going to pre-load it with our first item, the system directive. This puts up some guard rails for how the OpenAI can interpret and respond to our user prompt which will be coming later.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'msgs=[\\n        {\"role\": \"system\", \"content\": \"You are a hotel receptionist, your job is to help customers check in to their room. \\\\\\n        You can only respond when a customer asks you a question. Do not start the conversation. Always wait for a question.\\\\\\n        The customer does not speak your language, so keep your responses simple and clear.\"},\\n    ]',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"You\u2019ll notice our role for this is set to system. Our next role and content pair will be the \u2018user\u2019, and the prompt.\"}),/*#__PURE__*/e(\"p\",{children:\"Now let\u2019s go step-by-step using the Whisper features we learned earlier to implement our role-playing language coach.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'Def transcribe(audio):\\n    global msgs\\n\\n    media_file = open(audio, \"rb\")\\n\\n    # Step 1 - read in the French audio and convert it into English\\n    translation = openai.audio.translations.create(\\n        model=\"whisper-1\",\\n        file=media_file,\\n    )    \\n    msgs.append({\"role\": \"user\", \"content\": translation.text})\\n    if(len(translation.text)>10):\\n        print(translation.text)\\n\\n        # Step 2 - use the English text to generate a response\\n        response2 = openai.chat.completions.create(\\n            model=\"gpt-3.5-turbo\",\\n            messages=msgs\\n        )\\n        msgs.append({\"role\": \"assistant\", \"content\": response2.choices[0].message.content})\\n        print(\"step2: \", msgs)\\n\\n        # Step 3 - convert the response into French text\\n        response3 = openai.chat.completions.create(\\n            model=\"gpt-3.5-turbo\",\\n            messages=[\\n                    {\\n                        \"role\": \"user\",\\n                        \"content\": \"Translate the following text into French: \" + response2.choices[0].message.content\\n                    }\\n            ] )\\n        print(\"step3: \", msgs)\\n        ',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"In this code, the\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"transcribe\"})}),\"\\xa0function is taking us on a world tour of using OpenAI's speech and translation APIs to process an audio file. First, it opened up the audio file and used the Whisper model to transcribe French audio into English text. If the text was longer than 10 characters, it added this text to a global list called\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"msgs\"})}),\"\\xa0and printed it out for us. Then, it generated a response with the GPT-3.5-turbo model, added that to\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"msgs\"})}),\", and printed it.\"]}),/*#__PURE__*/e(\"p\",{children:\"We\u2019ve got two more steps to go but we need to take a bit of a pause because Step 4 is the one of the more complicated steps.\"}),/*#__PURE__*/t(\"p\",{children:[\"This is where it translates the English response into French and turns that French text into audio using the\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"tts-1\"})}),\"\\xa0text-to-speech model, streaming the audio output. Our PyAudio library comes in handy here. You\u2019ll notice in the code we had to set up some parameters to make this happen. Step 5 is rather easy. We just update our text on screen with the response.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'\\n        # step 4 - convert the french text to audio and stream the response\\n        stream = p.open(format=8,\\n                    channels=1,\\n                    rate=24_000,\\n                    output=True)\\n\\n        with openai.audio.speech.with_streaming_response.create(\\n            model=\"tts-1\",\\n            voice=\"alloy\",\\n            input=response3.choices[0].message.content,\\n            response_format=\"pcm\"\\n        ) as response:\\n            for chunk in response.iter_bytes(1024):\\n                    stream.write(chunk)\\n\\n        p.close(stream)\\n\\n        # step 5 - update the text on the screen\\n        chat = response3.choices[0].message.content\\n    else:\\n        chat = \\'\\'\\n    return chat',language:\"JSX\"})})}),/*#__PURE__*/e(\"p\",{children:\"Now to take advantage of that Gradio install earlier we are going to create a simple interface for this system:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'import gradio as gr\\ngr.Interface(\\n    fn=transcribe,\\n    live=True,\\n    inputs=gr.Audio(sources=\"microphone\", type=\"filepath\", streaming=True),\\n    outputs=\"text\",\\n).launch()',language:\"JSX\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Alright, let's dive into what this snippet is doing! Here, we're using Gradio to create an interface for our \",/*#__PURE__*/e(\"code\",{children:\"transcribe\"}),\" function. The \",/*#__PURE__*/e(\"code\",{children:\"gr.Interface\"}),\" is set up to call the \",/*#__PURE__*/e(\"code\",{children:\"transcribe\"}),\" function whenever it receives input. We've got it configured to take audio input directly from a microphone, with the audio being streamed as a file path. The output is then displayed as text. By setting \",/*#__PURE__*/e(\"code\",{children:\"live=True\"}),\", we're making sure that the interface processes the audio input in real-time. Finally, the \",/*#__PURE__*/e(\"code\",{children:\".launch()\"}),\" method kicks everything off, opening up the interface so users can start interacting with it.\"]}),/*#__PURE__*/e(\"p\",{children:\"Basically, this creates a web interface where users can speak into their microphone and receive text responses in real-time. Gradio is super powerful and this is only one of the things it does, so check it out when you have time.\"}),/*#__PURE__*/e(\"h2\",{children:\"Conclusion\"}),/*#__PURE__*/e(\"p\",{children:\"Throughout this guide, you learned how to create an interactive language learning tool using OpenAI's Whisper and ChatGPT models, combined with Gradio for a user-friendly interface. You explored how to transcribe and translate spoken language, generate responses, and convert text back into speech, all while understanding the integration of these technologies. By implementing these steps, you gained practical experience in building a real-time application that allows users to practice language skills by speaking into a microphone and receiving text responses. On top of all that, you now can build upon these principles to create a fully customizable language coach!\"}),/*#__PURE__*/t(\"h4\",{children:[\"If you had fun with this tutorial be sure to join the \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/practical-chatgpt-api-programming/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"OpenAI Application Explorers Meetup Group\"})}),\" to learn more about awesome apps you can build with AI\"]})]});export const richText1=/*#__PURE__*/t(i.Fragment,{children:[/*#__PURE__*/e(\"p\",{children:\"The Android Team Awareness Kit (ATAK) has revolutionized situational awareness and operational efficiency across various sectors. As a powerful mobile platform, ATAK provides real-time data sharing and collaboration capabilities that are essential for military operations, emergency response, and field operations. In this article, we\u2019ll explore the world of ATAK plugins and how they extend the functionality of this versatile tool. Some basic knowledge of Android app development will be required.\"}),/*#__PURE__*/e(\"p\",{children:\"This will be part 1 of a 2 part series. Feel free to follow along with the video from our latest meetup hosted by RIIS President Godfrey Nolan while reading through the tutorial.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{\"--aspect-ratio\":\"560 / 315\",aspectRatio:\"560 / 315\",height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js:Youtube\",children:t=>/*#__PURE__*/e(r,{...t,play:\"Off\",shouldMute:!0,thumbnail:\"Medium Quality\",url:\"https://youtu.be/3qSsMcYXrvI\"})})}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"What is ATAK?\"}),/*#__PURE__*/e(\"p\",{children:\"ATAK, or the Android Team Awareness Kit, is an open-source situational awareness and communication tool designed for both military and civilian use. It offers a range of features including mapping, geospatial capabilities, and communication functionalities. The modular architecture of ATAK allows for customization and extension through plugins, making it adaptable to various operational scenarios.\"}),/*#__PURE__*/e(\"p\",{children:\"Originally developed by the U.S. Air Force in the early 2000s, ATAK has evolved into a civilian version known as \u201CATAK-CIV,\u201D which was released about 5-6 years ago. This open-source nature has led to a thriving ecosystem of developers and users who continually enhance and expand ATAK\u2019s capabilities.\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"The Power of ATAK Plugins\"}),/*#__PURE__*/e(\"p\",{children:\"Plugins are at the heart of ATAK\u2019s extensibility. They allow users to add new features, customize the user interface, or integrate with external systems. This plugin architecture is one of the most appealing aspects of ATAK, as it enables users to tailor the application to their specific needs.\"}),/*#__PURE__*/e(\"p\",{children:\"Some key benefits of ATAK plugins include:\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Customization: Plugins can be developed to meet the unique requirements of different organizations or operational contexts.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Integration: ATAK can be integrated with various external systems and data sources through plugins.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Enhanced functionality: Plugins can add new tools and capabilities to the base ATAK application.\"})})]}),/*#__PURE__*/e(\"h3\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h3\",{children:/*#__PURE__*/e(\"strong\",{children:\"Core Features\"})}),/*#__PURE__*/t(\"ul\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Mapping and Geospatial Capabilities\"}),\": ATAK supports both online and offline mapping with high-resolution imagery and fast rendering. It can handle various standard formats and allows for collaborative mapping, including points, drawings, and locations of interest.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Communication\"}),\": The platform facilitates real-time data sharing, including chat, file sharing, photo sharing, video sharing, and streaming. It also supports radio controls and integration, as well as Voice over IP (VoIP) capabilities.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Navigation\"}),\": ATAK provides tools for navigation, including walking, hiking, driving, and air-ground coordination. It also offers elevation tools, heat maps, computed contour maps, and dynamic profiling.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Situational Awareness\"}),\": Features like precision targeting, surrounding land formation intelligence, and team emergency beacons enhance situational awareness. Users can mark, share, and track locations, and use network-aware geofences with triggers.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Customization and Extensibility\"}),\": The modular architecture of ATAK allows for extensive customization through plugins, enabling users to tailor the application to specific operational needs\"]})})]}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"ATAK Architecture\"}),/*#__PURE__*/e(\"p\",{children:\"The Android Team Awareness Kit (ATAK) and its related variants (WinTAK for Windows and iTAK for iOS) are part of a larger TAK ecosystem designed for situational awareness and communication. Here's an overview of the ATAK architecture and how it interacts with other TAK variants:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/1SZWIMUFJKz8yW6lEjgBA1jeo0Q.png\",srcSet:\"https://framerusercontent.com/images/1SZWIMUFJKz8yW6lEjgBA1jeo0Q.png?scale-down-to=512 512w,https://framerusercontent.com/images/1SZWIMUFJKz8yW6lEjgBA1jeo0Q.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/1SZWIMUFJKz8yW6lEjgBA1jeo0Q.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"p\",{children:\"A common setup would potentially include setting up your own network utilizing something like goTenna. Devices are then able to share data between each other on the network regardless of their TAK variant.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/jt9M1VeC3FV6zSjZVnZHOKKvQ8.png\",srcSet:\"https://framerusercontent.com/images/jt9M1VeC3FV6zSjZVnZHOKKvQ8.png?scale-down-to=512 512w,https://framerusercontent.com/images/jt9M1VeC3FV6zSjZVnZHOKKvQ8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/jt9M1VeC3FV6zSjZVnZHOKKvQ8.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Getting Started with ATAK Plugin Development\"}),/*#__PURE__*/t(\"p\",{children:[\"Before we get started, you should know, that you don\u2019t need a \",/*#__PURE__*/e(o,{href:\"http://tak.gov/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"tak.gov\"})}),\" login to get started, but there will be additional benefits if you have one.\"]}),/*#__PURE__*/t(\"p\",{children:[\"If you want to install any existing plugins such as the UAS Plugin Tool for flying drones, you first need to download and install the base ATAK-CIV (Civil Use) application from Google Play. This is the core ATAK app that you need before installing any plugins. You can then install any of the 30 or so plugins on Google Play or \",/*#__PURE__*/e(o,{href:\"http://tak.gov/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"tak.gov\"})}),\" which are then loaded into the core ATAK-CIV.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/WvPuLN4ub2qggOePDR2WSu9Fds0.png\",srcSet:\"https://framerusercontent.com/images/WvPuLN4ub2qggOePDR2WSu9Fds0.png?scale-down-to=512 512w,https://framerusercontent.com/images/WvPuLN4ub2qggOePDR2WSu9Fds0.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/WvPuLN4ub2qggOePDR2WSu9Fds0.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"p\",{children:\"However, if you want to create your own plugin, then we don\u2019t need ATAK-CIV just yet. We\u2019ll talk about how to deploy our own plugins in Part 2 of this blog.\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"The Hello World Example Plugin\"}),/*#__PURE__*/e(\"p\",{children:\"Let\u2019s take a look at some of the sample plugins to get us started. The Hello World example is not what I\u2019d expect from its name. It\u2019s a comprehensive plugin that shows many of the capabilities of ATAK plugins. The second example plugin the plugintemplate is more of a traditional HelloWorld example.\"}),/*#__PURE__*/t(\"p\",{children:[\"Download the ATAK SDK from the \",/*#__PURE__*/e(o,{href:\"https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"official GitHub repository\"})}),\". Unzip the SDK and create a \u201Cplugins\u201D directory within it. Within the SDK folder from the version you\u2019ve downloaded navigate to atak-civ/plugins or plugin-templates folder. Copy the HelloWorld example in \u201Cplugin-examples\u201D into the newly created \u201Cplugins\u201D folder.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/1RbD26n5inBZ3MmuZ003f8Wbhg.png\",srcSet:\"https://framerusercontent.com/images/1RbD26n5inBZ3MmuZ003f8Wbhg.png?scale-down-to=512 512w,https://framerusercontent.com/images/1RbD26n5inBZ3MmuZ003f8Wbhg.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/1RbD26n5inBZ3MmuZ003f8Wbhg.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/t(\"p\",{children:[\"Click on the \",/*#__PURE__*/e(\"code\",{children:\"helloworld\"}),\" file within it.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/P4AWfNEaAw8FyOoAQ363r2bo.png\",srcSet:\"https://framerusercontent.com/images/P4AWfNEaAw8FyOoAQ363r2bo.png?scale-down-to=512 512w,https://framerusercontent.com/images/P4AWfNEaAw8FyOoAQ363r2bo.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/P4AWfNEaAw8FyOoAQ363r2bo.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"p\",{children:\"It would be nice if you could just launch this and be ready to go, but there\u2019s a couple of things we need to do to get Android Studio to behave and not harass us with error messages.\"}),/*#__PURE__*/e(\"ol\",{children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Go into the \",/*#__PURE__*/e(\"code\",{children:\"local.properties\"}),\" file add the SDK directory and any other information seen in the example below that you are missing:\"]})})}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"sdk.dir=c\\\\:\\\\\\\\Users\\\\\\\\admin\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Android\\\\\\\\Sdk\\ntakDebugKeyFile=<ABSOLUTE_PLUGIN_PATH>\\\\\\\\debug.keystore\\ntakDebugKeyFilePassword=android\\ntakDebugAlias=androiddebugkey\\ntakDebugKeyPassword=android\\n\\ntakReleaseKeyFile=<ABSOLUTE_PLUGIN_PATH>\\\\\\\\release.keystore\\ntakReleaseKeyFilePassword=android\\ntakReleaseAlias=androidreleasekey\\ntakDebugKeyPassword=android\",language:\"Ruby\"})})}),/*#__PURE__*/e(\"ol\",{start:\"2\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Create debug and release keystores using the keytool command.\"})})}),/*#__PURE__*/e(\"ol\",{style:{\"--list-style-type\":\"lower-alpha\"},children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"For a debug keystore\"})})}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000\",language:\"JSX\"})})}),/*#__PURE__*/e(\"p\",{children:\"b.  Fore a release keystore\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000\",language:\"JSX\"})})}),/*#__PURE__*/e(\"ol\",{start:\"3\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Change Gradle plugin to 4.2.2 and the Gradle version to 6.9.1\"})})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/YUvRk1uggnoRlHrX42TjyL5gZeY.png\",srcSet:\"https://framerusercontent.com/images/YUvRk1uggnoRlHrX42TjyL5gZeY.png?scale-down-to=512 512w,https://framerusercontent.com/images/YUvRk1uggnoRlHrX42TjyL5gZeY.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/YUvRk1uggnoRlHrX42TjyL5gZeY.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"ol\",{start:\"4\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Update the Gradle version by going to Settings>Build, Execution, Deployment>Build Tools>Gradle to Gradle JDK: 11\"})})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"413\",src:\"https://framerusercontent.com/images/cv40tZYWD0Xn7Tp9dfxaYAK7w.png\",srcSet:\"https://framerusercontent.com/images/cv40tZYWD0Xn7Tp9dfxaYAK7w.png?scale-down-to=512 512w,https://framerusercontent.com/images/cv40tZYWD0Xn7Tp9dfxaYAK7w.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/cv40tZYWD0Xn7Tp9dfxaYAK7w.png 1106w\",style:{aspectRatio:\"1106 / 827\"},width:\"553\"}),/*#__PURE__*/e(\"ol\",{start:\"5\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Change the build.gradle file at the app level to the following:\"})})}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'buildscript {\\n\t\text.PLUGIN_VERSION = \"1.0\"\\n\t\text.ATAK_VERSION = \"4.6.0\"\\n\t\t\\n\t\tdef takdevVersion : String = \\'2.+\\'\\n\t\t\\n\t\text.getValueFromPropertiesFile = { propFile, key ->\\n\t\t\t\tif(!propFile.isFile() || !propFile.canRead())\\n\t\t\t\t\t\treturn null\\n\t\t\t\tdef prop = new Properties()\\n\t\t\t\tdef reader = propFile.newReader()\\n\t\t\t\ttry {\\n\t\t\t\t\t\tprop.load(reader)\\n\t\t\t\t} finally {\\n\t\t\t\t\t\treader.close()\\n\t\t\t\t}\\n\t\t\t\treturn prop.get(key)\\n}',language:\"Ruby\"})})}),/*#__PURE__*/e(\"ol\",{start:\"6\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Edit the app configuration to work with the plugin. Since plugins don\u2019t launch as standalone apps, you\u2019ll need to modify the configuration to prevent Android Studio from attempting to launch an activity.\"})})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"482\",src:\"https://framerusercontent.com/images/FVqXFV32kjCvpVeupu7sD6V44cg.png\",srcSet:\"https://framerusercontent.com/images/FVqXFV32kjCvpVeupu7sD6V44cg.png?scale-down-to=512 512w,https://framerusercontent.com/images/FVqXFV32kjCvpVeupu7sD6V44cg.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/FVqXFV32kjCvpVeupu7sD6V44cg.png 1227w\",style:{aspectRatio:\"1227 / 965\"},width:\"613\"}),/*#__PURE__*/e(\"ol\",{start:\"7\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Install the \",/*#__PURE__*/e(o,{href:\"https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"ATAK APK from the SDK\"})}),\", not the one from Google Play. This ensures compatibility with your development environment.\"]})})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"266\",src:\"https://framerusercontent.com/images/VF2bzkJ8X4iwiLWg5sTkqKrZquM.png\",srcSet:\"https://framerusercontent.com/images/VF2bzkJ8X4iwiLWg5sTkqKrZquM.png?scale-down-to=512 512w,https://framerusercontent.com/images/VF2bzkJ8X4iwiLWg5sTkqKrZquM.png 966w\",style:{aspectRatio:\"966 / 533\"},width:\"483\"}),/*#__PURE__*/e(\"ol\",{start:\"8\",children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Change the build variants and change \",/*#__PURE__*/e(\"code\",{children:\":app\"}),\" to \",/*#__PURE__*/e(\"code\",{children:\"civDebug\"})]})})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"516\",src:\"https://framerusercontent.com/images/GZ7MN2Rshns9El4vz45vmlXXfA.png\",srcSet:\"https://framerusercontent.com/images/GZ7MN2Rshns9El4vz45vmlXXfA.png?scale-down-to=1024 850w,https://framerusercontent.com/images/GZ7MN2Rshns9El4vz45vmlXXfA.png 858w\",style:{aspectRatio:\"858 / 1033\"},width:\"429\"}),/*#__PURE__*/e(\"p\",{children:\"When you try to run the app, most Android devices will try and prevent you from running applications not downloaded from Google Play, so you will probably see the following message.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"223\",src:\"https://framerusercontent.com/images/DrzbtuLngX0EPKkxq59omA6Asc.png\",srcSet:\"https://framerusercontent.com/images/DrzbtuLngX0EPKkxq59omA6Asc.png?scale-down-to=512 512w,https://framerusercontent.com/images/DrzbtuLngX0EPKkxq59omA6Asc.png 993w\",style:{aspectRatio:\"993 / 447\"},width:\"496\"}),/*#__PURE__*/t(\"p\",{children:[\"Click on more details and then \",/*#__PURE__*/e(\"code\",{children:\"Install Anyway\"}),\".\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"245\",src:\"https://framerusercontent.com/images/ATJDrOQcGdGHliW3keGbM2j5auU.png\",srcSet:\"https://framerusercontent.com/images/ATJDrOQcGdGHliW3keGbM2j5auU.png?scale-down-to=512 512w,https://framerusercontent.com/images/ATJDrOQcGdGHliW3keGbM2j5auU.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/ATJDrOQcGdGHliW3keGbM2j5auU.png 1092w\",style:{aspectRatio:\"1092 / 491\"},width:\"546\"}),/*#__PURE__*/e(\"p\",{children:\"Okay, if all goes well, you should see the following app interface load:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"382\",src:\"https://framerusercontent.com/images/kc6uFUnJzZFldOe9nkwdvvjlj8.png\",srcSet:\"https://framerusercontent.com/images/kc6uFUnJzZFldOe9nkwdvvjlj8.png?scale-down-to=512 512w,https://framerusercontent.com/images/kc6uFUnJzZFldOe9nkwdvvjlj8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/kc6uFUnJzZFldOe9nkwdvvjlj8.png 1696w\",style:{aspectRatio:\"1696 / 764\"},width:\"848\"}),/*#__PURE__*/e(\"p\",{children:\"Wow, that\u2019s quite the big Hello World example, but it\u2019s kind of nice because it gives you a great overview of the stock capabilities within the the framework. Be sure to have a peek around and get familiar with all of the options.\"}),/*#__PURE__*/t(\"p\",{children:[\"You can see the work that goes into this beautifully retro layout in the \",/*#__PURE__*/e(\"code\",{children:\"AndroidTacticalAssaultKit-CIV/plugin-examples/helloworld/app/src/main/res/layout/hello_world_layout.xml\"}),\" file.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\\n   android:layout_width=\"match_parent\"\\n   android:layout_height=\"match_parent\"\\n   android:orientation=\"vertical\" >\\n\\n    <ScrollView\\n        android:layout_width=\"match_parent\"\\n        android:layout_height=\"wrap_content\"\\n        android:layout_marginLeft=\"3dp\"\\n        android:layout_marginRight=\"3dp\"\\n        android:fadeScrollbars=\"false\">\\n\\n        <LinearLayout\\n            android:layout_width=\"match_parent\"\\n            android:layout_height=\"wrap_content\"\\n            android:orientation=\"vertical\">\\n\\n            <TextView\\n                android:id=\"@+id/textView\"\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"wrap_content\"\\n                android:text=\"Hello, World\"\\n                android:textColor=\"@android:color/white\"\\n                android:textSize=\"20sp\" />\\n\\n            <RelativeLayout\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"1dp\"\\n                android:layout_margin=\"3dp\"\\n                android:background=\"@android:color/white\">\\n\\n            </RelativeLayout>\\n\\n            <TextView\\n                android:id=\"@+id/longPressTextView\"\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"wrap_content\"\\n                android:text=\"Long press a button for a brief descripton\"\\n                android:textColor=\"@android:color/white\"\\n                android:textSize=\"15sp\" />\\n\\n            <TextView\\n                android:id=\"@+id/clickTextView\"\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"wrap_content\"\\n                android:text=\"Tap a button for a demonstration\"\\n                android:textColor=\"@android:color/white\"\\n                android:textSize=\"15sp\" />\\n\\n            <RelativeLayout\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"1dp\"\\n                android:layout_margin=\"3dp\"\\n                android:background=\"@android:color/white\">\\n\\n            </RelativeLayout>\\n\\n            <TextView\\n                android:id=\"@+id/layoutExamples\"\\n                android:layout_width=\"match_parent\"\\n                android:layout_height=\"wrap_content\"\\n                android:text=\"Layout Examples\"\\n                android:textColor=\"@android:color/white\"\\n                android:textSize=\"18sp\" />\\n\\n            <Button\\n                android:id=\"@+id/largerButton\"\\n                style=\"@style/darkButton\"\\n                android:layout_width=\"wrap_content\"\\n                android:layout_height=\"wrap_content\"\\n                android:padding=\"6dp\"\\n                android:text=\"Larger\" />\\n...',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"We stopped at the \",/*#__PURE__*/e(\"code\",{children:\"largerButton\"}),\" button because you can sort of get the idea of where this goes.\"]}),/*#__PURE__*/t(\"p\",{children:[\"Each of those buttons need to be attached to a specific activity for them to do anything. You can see where this is happening in the \",/*#__PURE__*/e(\"code\",{children:\"plugin-examples/helloworld/app/src/main/java/com/atakmap/android/helloworld/HelloWorldDropDownReceiver.java\"}),\" file. For each of these buttons there\u2019s going to be a listener and a function like this one below for the \",/*#__PURE__*/e(\"code\",{children:\"largerButton\"}),\":\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"        final Button larger = helloView\\n                .findViewById(R.id.largerButton);\\n        larger.setOnClickListener(new OnClickListener() {\\n\\n            @Override\\n            public void onClick(View v) {\\n                resize(FULL_WIDTH, HALF_HEIGHT);\\n            }\\n        });\",language:\"Java\"})})}),/*#__PURE__*/e(\"p\",{children:\"This is pretty simple. It just says listen for a button click and when you see one resize to full width and half height.\"}),/*#__PURE__*/e(\"p\",{children:\"Feel free to poke around and investigate to learn more about ATAK capabilities. The code in the Hello World app includes lots of helpful comments to point you in the right direction.\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"Creating Your Second ATAK Plugin: Integrating MavSDK\"}),/*#__PURE__*/e(\"p\",{children:\"After successfully creating the \u201CHello World\u201D plugin, let\u2019s move on to a much simpler example that integrates drone functionality using MavSDK. This plugin builds on the pluginTemplate example and will demonstrate how to connect to a MavSDK server and display real-time position data from a drone.\"}),/*#__PURE__*/t(\"p\",{children:[\"Before we get started, if you are unfamiliar with the MAVSDK, check out our tutorial from last month\u2019s meetup \",/*#__PURE__*/e(o,{href:\"https://www.riis.com/blog/mavsdk-on-android\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"MAVSDK on Android\"})}),\". We will only briefly cover the MAVSDK-specific steps in this tutorial.\"]}),/*#__PURE__*/t(\"p\",{children:[\"Okay, navigate back to the \",/*#__PURE__*/e(\"code\",{children:\"plugins\"}),\" or \",/*#__PURE__*/e(\"code\",{children:\"plugin-templates\"}),\" folder and look for the \",/*#__PURE__*/e(\"code\",{children:\"plugintemplate\"}),\" file. This file functions more like a traditional Hello World example as it is the barebones you will need to build your own. Refer to steps 1 through 8 of the Hello World section for the basic setup. The main files we are going to be concerned with going forward are \",/*#__PURE__*/e(\"code\",{children:\"PluginTemplateDropDownReceiver.java\"}),\", \",/*#__PURE__*/e(\"code\",{children:\"PluginTemplateMapComponent.java\"}),\" and \",/*#__PURE__*/e(\"code\",{children:\"main_layout.xml\"}),\" .\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/oFJ5Xx79a9f4rdBZIwCfsz8gOqQ.png\",srcSet:\"https://framerusercontent.com/images/oFJ5Xx79a9f4rdBZIwCfsz8gOqQ.png?scale-down-to=512 512w,https://framerusercontent.com/images/oFJ5Xx79a9f4rdBZIwCfsz8gOqQ.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/oFJ5Xx79a9f4rdBZIwCfsz8gOqQ.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"Creating the User Interface\"}),/*#__PURE__*/t(\"p\",{children:[\"To keep things simple for our first MAVSDK plugin, we are going to focus on displaying the latitude and longitude of our drone. First let\u2019s set up a simple layout in our \",/*#__PURE__*/e(\"code\",{children:\"main_layout.xml\"})]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n<ScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\\n    android:layout_width=\"match_parent\"\\n    android:layout_height=\"wrap_content\"\\n    android:fadeScrollbars=\"false\"\\n    android:layout_marginLeft=\"3dp\"\\n    android:layout_marginRight=\"3dp\">\\n\\n    <LinearLayout\\n        android:layout_width=\"match_parent\"\\n        android:layout_height=\"wrap_content\"\\n        android:orientation=\"vertical\" >\\n\\n        <TextView\\n            android:layout_width=\"wrap_content\"\\n            android:layout_height=\"wrap_content\"\\n            android:text=\"@string/app_name\" />\\n            \\n        <TextView \\n\t\t        android:id=\"@+id/positionTextView\"\\n\t\t        android:layout_width=\"wrap_content\"\\n\t\t        android:layout_height=\"wrap_content\"\\n\t\t        android:text=\"@string/position_lat_long\" />\\n\\n    </LinearLayout>\\n</ScrollView>',language:\"HTML\"})})}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"Integrating MavSDK\"}),/*#__PURE__*/t(\"p\",{children:[\"Modern Android applications are rarely coded in Java anymore. The good news is you can easily convert your Java code to Kotlin within Android Studio by going to \",/*#__PURE__*/e(\"strong\",{children:\"Code > Convert Java File to Kotlin File.\"}),\" This is great, because we can easily transmute the code in \",/*#__PURE__*/e(\"code\",{children:\"PluginTemplateDropDownReceiver.java\"}),\" into a \",/*#__PURE__*/e(\"code\",{children:\"PluginTemplateDropDownReceiver.kt\"}),\" file.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'package com.atakmap.android.plugintemplate\\n\\nimport android.content.Context\\nimport android.content.Intent\\nimport android.view.View\\nimport com.atakmap.coremap.maps.coords.GeoPoint\\nimport com.atak.plugins.impl.PluginLayoutInflater\\nimport com.atakmap.android.maps.MapView\\nimport com.atakmap.android.plugintemplate.plugin.R\\nimport com.atakmap.android.dropdown.DropDown\\nimport com.atakmap.android.dropdown.DropDownReceiver\\nimport com.atakmap.coremap.log.Log\\n\\nclass PluginTemplateDropDownReceiver(\\n    mapView: MapView,\\n    private val context: Context\\n) : DropDownReceiver(mapView), DropDown.OnStateListener {\\n\\n    companion object {\\n        private const val TAG = \"PluginTemplateDropDownReceiver\"\\n        const val SHOW_PLUGIN = \"com.atakmap.android.plugintemplate.SHOW_PLUGIN\"\\n    }\\n\\n    private val templateView: View = PluginLayoutInflater.inflate(context, R.layout.main_layout, null)\\n\\n    override fun disposeImpl() {}\\n\\n    override fun onReceive(context: Context, intent: Intent) {\\n        val action = intent.action ?: return\\n        if (action == SHOW_PLUGIN) {\\n            Log.d(TAG, \"showing plugin drop down\")\\n            showDropDown(templateView, HALF_WIDTH, FULL_HEIGHT, FULL_WIDTH, HALF_HEIGHT, false, this)\\n        }\\n    }\\n\\n    override fun onDropDownSelectionRemoved() {}\\n\\n    override fun onDropDownVisible(v: Boolean) {}\\n\\n    override fun onDropDownSizeChanged(width: Double, height: Double) {}\\n\\n    override fun onDropDownClose() {}\\n}\\n\\n',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"We are going to add the following code between our \",/*#__PURE__*/e(\"code\",{children:\"private val templateView\"}),\" and our \",/*#__PURE__*/e(\"code\",{children:\"public override fun disposeImpl()\"}),\" to inject our position coordinates into the layout.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'private val positionTextView: TextView = templateView.findViewById(R.id.positionTextView)\\n\\ninit {\\n\t\tCouroutineScope(Dispatchers.IO).launch {this: CoroutineScope\\n\t\t\t\tposition.collet {pair ->\\n\t\t\t\t\t\tval newPositionString = \"Position: (${pair.first}, ${pair.second}\"\\n\t\t\t\t\t\twithContext(Dispatchers.Main) {this: CoroutineScope\\n\t\t\t\t\t\t\t\tpositionTextView.text = newPositionString\\n\t\t\t\t\t\t}\\n\t\t\t\t}\\n\t\t}\\n}',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Now we can do the same conversion to our \",/*#__PURE__*/e(\"code\",{children:\"PluginTemplateMapComponent.java\"}),\" file.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'package com.atakmap.android.plugintemplate\\n\\nimport android.content.Context\\nimport android.content.Intent\\nimport com.atakmap.android.ipc.AtakBroadcast.DocumentedIntentFilter\\nimport com.atakmap.android.maps.MapView\\nimport com.atakmap.android.dropdown.DropDownMapComponent\\nimport com.atakmap.coremap.log.Log\\nimport com.atakmap.android.plugintemplate.plugin.R\\n\\nclass PluginTemplateMapComponent : DropDownMapComponent() {\\n    private companion object {\\n        private const val TAG = \"PluginTemplateMapComponent\"\\n    }\\n\\n    private lateinit var pluginContext: Context\\n    private lateinit var ddr: PluginTemplateDropDownReceiver\\n   \\n\\n    override fun onCreate(context: Context, intent: Intent, view: MapView) {\\n        context.setTheme(R.style.ATAKPluginTheme)\\n        super.onCreate(context, intent, view)\\n        pluginContext = context\\n\\n        ddr = PluginTemplateDropDownReceiver(view, context)\\n\\n        Log.d(TAG, \"registering the plugin filter\")\\n        val ddFilter = DocumentedIntentFilter()\\n        ddFilter.addAction(PluginTemplateDropDownReceiver.SHOW_PLUGIN)\\n        registerDropDownReceiver(ddr, ddFilter)\\n    }\\n\\n    override fun onDestroyImpl(context: Context, view: MapView) {\\n        super.onDestroyImpl(context, view)\\n    }\\n}',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"First, let\u2019s add a few variables for our position data just under \",/*#__PURE__*/e(\"code\",{children:\"private var ddr\"}),\":\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"private val _position = MutableStateFlow(Pair(0.toDouble(), 0.toDouble()))\\nprivate val position : StateFlow<Pair<Double, Double> = _position\",language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Then we need to add position to the ddr variable within the override fun \",/*#__PURE__*/e(\"code\",{children:\"onCreate()\"})]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"ddr = PluginTemplateDropDownReceiver(view, context, position)\",language:\"JSX\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Finally within the \",/*#__PURE__*/e(\"code\",{children:\"override fun onCreate()\"}),\" we want to add the following at the very end.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"if (!isMavsdkServerRunning) {\\n\t\trunMavSDKServer()\\n}\",language:\"Java\"})})}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"Testing the Plugin\"}),/*#__PURE__*/t(\"p\",{children:[\"Here\u2019s one last reminder to check out last month\u2019s \",/*#__PURE__*/e(o,{href:\"https://www.riis.com/blog/mavsdk-on-android\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"MAVSDK on Android\"})}),\" tutorial for how setup the dependencies and SITL test.\"]}),/*#__PURE__*/e(\"p\",{children:\"To test the plugin, you\u2019ll need to run a PX4 simulator. You can use a Docker container we used in the above tutorial to start a headless Gazebo PX4 simulator.\"}),/*#__PURE__*/e(\"p\",{children:\"Once the simulator is running, compile and deploy your plugin to ATAK. You should see the drone\u2019s position updating in real-time in the logcat output.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"190\",src:\"https://framerusercontent.com/images/J904w6ZDXOwNgr6qa9fCgmFXuWM.png\",srcSet:\"https://framerusercontent.com/images/J904w6ZDXOwNgr6qa9fCgmFXuWM.png?scale-down-to=512 512w,https://framerusercontent.com/images/J904w6ZDXOwNgr6qa9fCgmFXuWM.png 823w\",style:{aspectRatio:\"823 / 381\"},width:\"411\"}),/*#__PURE__*/e(\"h1\",{children:\"Conclusion\"}),/*#__PURE__*/e(\"p\",{children:\"In this tutorial, we\u2019ve explored the process of creating ATAK plugins, from a not so simple \u201CHello World\u201D example as well as MavSDK integration for drone control. We\u2019ve covered the basics of setting up the development environment, creating layouts, and integrating with external systems like MavSDK.\"}),/*#__PURE__*/e(\"p\",{children:\"ATAK plugins provide a powerful way to extend the functionality of the ATAK platform, enabling custom solutions for various operational scenarios. By leveraging the plugin architecture, developers can create tailored tools that enhance situational awareness and operational efficiency.\"}),/*#__PURE__*/e(\"p\",{children:\"As you continue to develop ATAK plugins, consider exploring more advanced features such as custom map overlays, sensor integrations, or specialized communication modules using the HelloWorld example as a guide. The ATAK community and resources mentioned earlier can provide valuable support and inspiration for your future projects.\"}),/*#__PURE__*/e(\"p\",{children:\"Remember to always test your plugins thoroughly and consider the security implications when working with sensitive data or in operational environments. Happy coding, and enjoy building powerful situational awareness tools with ATAK!\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Additional Resources\"}),/*#__PURE__*/t(\"ul\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://www.ballantyne.online/developing-atak-plugin-101/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://www.ballantyne.online/developing-atak-plugin-101/\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://toyon.github.io/LearnATAK/docs/setup/atak_plugin/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://toyon.github.io/LearnATAK/docs/setup/atak_plugin/\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://www.civtak.org/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://www.civtak.org/\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://play.google.com/store/apps/details?id=com.atakmap.app.civ\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://play.google.com/store/apps/details?id=com.atakmap.app.civ\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://play.google.com/store/apps/details?id=com.atakmap.android.uastool.plugin\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://play.google.com/store/apps/details?id=com.atakmap.android.uastool.plugin\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://github.com/riis/atak-tutorial\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://github.com/riis/atak-tutorial\"})})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(o,{href:\"https://www.riis.com/blog/mavsdk-on-android\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"https://www.riis.com/blog/mavsdk-on-android\"})})})})]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/t(\"h3\",{children:[\"Stay tuned for Part 2 and be sure to join us at our next \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/drone-software-meetup-group/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"Drone Software Developer Meetup\"})}),\" for more great walkthroughs like this one!\"]})]});export const richText2=/*#__PURE__*/t(i.Fragment,{children:[/*#__PURE__*/e(\"p\",{children:\"In today\u2019s digital landscape, chatbots have become an essential tool for businesses to enhance customer engagement and provide instant support. By leveraging the power of ChatGPT and fine-tuning techniques, you can create a personalized chatbot tailored specifically for your website. This article will guide you through the process of building your own customized chatbot using OpenAI\u2019s ChatGPT model. Godfrey Nolan, President at RIIS, recently demonstrated how easy this can be at The OpenAI Application Explorers meetup. You can follow along in the video or read the post below to start building your own AI-powered chat bot.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{\"--aspect-ratio\":\"560 / 315\",aspectRatio:\"560 / 315\",height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js:Youtube\",children:t=>/*#__PURE__*/e(r,{...t,play:\"Off\",shouldMute:!0,thumbnail:\"Medium Quality\",url:\"https://www.youtube.com/watch?v=Jyo6YCM-j0k\"})})}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Introduction\"}),/*#__PURE__*/e(\"p\",{children:\"Chatbots powered by artificial intelligence have revolutionized the way businesses interact with their customers. They offer 24/7 support, and instant responses, and can handle a wide range of inquiries. However, generic chatbots may not always align with your brand\u2019s voice or specific domain knowledge. This is where fine-tuning comes into play, allowing you to create a chatbot that truly represents your business.\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"The Basics of Fine-Tuning\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"360\",src:\"https://framerusercontent.com/images/gCxXezsKVNMV34yVHu4Y0hMvSs.png\",srcSet:\"https://framerusercontent.com/images/gCxXezsKVNMV34yVHu4Y0hMvSs.png?scale-down-to=512 512w,https://framerusercontent.com/images/gCxXezsKVNMV34yVHu4Y0hMvSs.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/gCxXezsKVNMV34yVHu4Y0hMvSs.png 1280w\",style:{aspectRatio:\"1280 / 720\"},width:\"640\"}),/*#__PURE__*/e(\"p\",{children:\"Fine-tuning is a process that adapts a pre-trained language model to a specific task or domain. By training the model on a smaller, task-specific dataset, you can optimize its performance for your particular use case. This technique allows the model to leverage its existing knowledge while specializing in your area of interest.\"}),/*#__PURE__*/e(\"h2\",{children:\"Benefits of Fine-Tuning\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Improved accuracy for domain-specific queries\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Better alignment with your brand\u2019s tone and voice\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Reduced likelihood of generating irrelevant or incorrect information\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Enhanced ability to handle specialized terminology or jargon\"})})]}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Data Preparation\"}),/*#__PURE__*/e(\"p\",{children:\"The first step in creating your customized chatbot is preparing the training data. This data should consist of question-answer pairs that represent the types of interactions you expect your chatbot to handle.\"}),/*#__PURE__*/e(\"h2\",{children:\"Creating the Training Dataset\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Compile a list of common questions and their corresponding answers relevant to your business or website.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Format the data as a JSON file with each entry containing a user message and an assistant response.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Aim for at least 50-100 question-answer pairs, but remember that more data generally leads to better results.\"})})]}),/*#__PURE__*/e(\"p\",{children:\"Here\u2019s an example of how your input data might look:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'[    \\n\t{        \\n\t\t\"messages\": [             \\n\t\t\t{\"role\": \"user\", \"content\": \"How do I check my data usage?\"},            \\n\t\t\t{\"role\": \"assistant\", \"content\": \"You can check your data usage by logging into your account on our website or using our mobile app.\"}        \\n\t\t\t]    \\n\t},    \\n\t{        \\n\t\t\"messages\": [             \\n\t\t\t{\"role\": \"user\", \"content\": \"What should I do if my internet is slow?\"},            \\n\t\t\t{\"role\": \"assistant\", \"content\": \"If your internet is slow, try restarting your modem and router, running a speed test, and ensuring your devices are within range of the Wi-Fi signal. If the problem persists, contact our support team for further assistance.\"}        \\n\t\t\t]    \\n\t}\\n]',language:\"JavaScript\"})})}),/*#__PURE__*/e(\"h2\",{children:\"Converting to JSONL Format\"}),/*#__PURE__*/e(\"p\",{children:\"OpenAI\u2019s fine-tuning process requires the input data to be in JSONL (JSON Lines) format. You can use a simple Python script to convert your JSON file to JSONL:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"import json\\n\\ninput_jsonl_file = \\\"input_data.jsonl\\\"\\ninput_json_file = \\\"input_data.json\\\"\\n\\nwith open(input_json_file, 'r') as json_file:\\n  data = json.load(json_file)\\n\\nwith open(input_jsonl_file, 'w') as jsonl_file:\\n  for entry in data:\\n    jsonl_file.write(json.dumps(entry) + '\\\\')\\n\\nprint(\\\"Conversion to JSONL complete.\\\")\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"After running the script on your data, the output should look something like this:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"195\",src:\"https://framerusercontent.com/images/ZZnJr9Fk70RgAXrp5VBoQ3fkJw.png\",srcSet:\"https://framerusercontent.com/images/ZZnJr9Fk70RgAXrp5VBoQ3fkJw.png?scale-down-to=512 512w,https://framerusercontent.com/images/ZZnJr9Fk70RgAXrp5VBoQ3fkJw.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/ZZnJr9Fk70RgAXrp5VBoQ3fkJw.png 1754w\",style:{aspectRatio:\"1754 / 391\"},width:\"877\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Uploading the Training Data\"}),/*#__PURE__*/e(\"p\",{children:\"Once your data is prepared, the next step is to upload it to OpenAI for fine-tuning. This can be done using the OpenAI API or manually through the OpenAI playground on the website. If you want to do this programmatically use the script below:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'import config\\nfrom openai import OpenAI\\n\\nclient = OpenAI(api_key=config.OPENAI_API_KEY)\\n\\ninput_jsonl_file = \"input_data.jsonl\"\\nfile = client.files.create(\\n  file=open(input_jsonl_file, \"rb\"),\\n  purpose=\"fine-tune\")\\n\\nprint(\"File has been uploaded to OpenAI with id \", file.id)',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Make sure to store your OpenAI API key securely, preferably in a separate configuration file. This is referenced in the code above with the \",/*#__PURE__*/e(\"code\",{children:\"import config\"}),\" at the top, and then the \",/*#__PURE__*/e(\"code\",{children:\"config.OPEN_API_KEY\"}),\" method when setting the client variable. Your \",/*#__PURE__*/e(\"code\",{children:\"config.py\"}),\" file should look something like this:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'OPENAI_API_KEY=\"{{INSERT YOUR OPENAI API KEY HERE}}\"',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"If your file was uploaded successfully you should see this message in the command line.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"13\",src:\"https://framerusercontent.com/images/zqLqSaRSWrQBQzXagP7PLYTCJI.png\",srcSet:\"https://framerusercontent.com/images/zqLqSaRSWrQBQzXagP7PLYTCJI.png?scale-down-to=512 512w,https://framerusercontent.com/images/zqLqSaRSWrQBQzXagP7PLYTCJI.png 741w\",style:{aspectRatio:\"741 / 27\"},width:\"370\"}),/*#__PURE__*/e(\"p\",{children:\"You can also see this in more detail within the OpenAI dashboard under the Files tab.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"198\",src:\"https://framerusercontent.com/images/bScz1J9r4LXv3JYhqRISgTHYrs.png\",srcSet:\"https://framerusercontent.com/images/bScz1J9r4LXv3JYhqRISgTHYrs.png?scale-down-to=512 512w,https://framerusercontent.com/images/bScz1J9r4LXv3JYhqRISgTHYrs.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/bScz1J9r4LXv3JYhqRISgTHYrs.png 1275w\",style:{aspectRatio:\"1275 / 396\"},width:\"637\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Creating the Fine-Tuning Job\"}),/*#__PURE__*/e(\"p\",{children:\"After uploading your training data, you can create a fine-tuning job:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'from openai import OpenAI\\nimport config\\n\\nclient = OpenAI(api_key=config.OPENAI_API_KEY)\\n\\nfile_id = \"file-sO8gDViouzBHiKefhzXXXXXX\"\\n\\nft_job = client.fine_tuning.jobs.create(\\n  training_file=file_id,\\n  model=\"gpt-3.5-turbo\"\\n)\\n\\nprint(\"Fine Tune Job has been created with id \", ft_job.id)\\n\\nevents = client.fine_tuning.jobs.list_events(fine_tuning_job_id=ft_job.id, limit=10)\\n\\nprint(events)',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Be sure and replace your \",/*#__PURE__*/e(\"code\",{children:\"file_id\"}),\" with the file ID for your specific training data before running the script.\"]}),/*#__PURE__*/e(\"p\",{children:\"If the job has successfully been created, you will see a message like this in the command line.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"74\",src:\"https://framerusercontent.com/images/h6g6L6WepB1TWH8lXejOWwWDTA.png\",srcSet:\"https://framerusercontent.com/images/h6g6L6WepB1TWH8lXejOWwWDTA.png?scale-down-to=512 512w,https://framerusercontent.com/images/h6g6L6WepB1TWH8lXejOWwWDTA.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/h6g6L6WepB1TWH8lXejOWwWDTA.png 1252w\",style:{aspectRatio:\"1252 / 148\"},width:\"626\"}),/*#__PURE__*/t(\"p\",{children:[\"In this response, look for the \",/*#__PURE__*/e(\"code\",{children:\"ftjob-\"}),\" prefix to find your fine-tuning job id. If you go back to the OpenAI dashboard again in the Fine-tuning tab, you can find the job.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"290\",src:\"https://framerusercontent.com/images/MAQ1vW82haxNpz803CCCBLzlMk.png\",srcSet:\"https://framerusercontent.com/images/MAQ1vW82haxNpz803CCCBLzlMk.png?scale-down-to=512 512w,https://framerusercontent.com/images/MAQ1vW82haxNpz803CCCBLzlMk.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/MAQ1vW82haxNpz803CCCBLzlMk.png 1327w\",style:{aspectRatio:\"1327 / 580\"},width:\"663\"}),/*#__PURE__*/e(\"p\",{children:\"This process may take some time, depending on the size of your dataset and the current load on OpenAI\u2019s servers. You can monitor the progress of your fine-tuning job through the OpenAI dashboard or by querying the API.\"}),/*#__PURE__*/e(\"p\",{children:\"You can get some feedback on the job process, but how useful it will be is debatable.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"379\",src:\"https://framerusercontent.com/images/M8JpKO7eycJP0DwKB0cgV1j8k8.png\",srcSet:\"https://framerusercontent.com/images/M8JpKO7eycJP0DwKB0cgV1j8k8.png?scale-down-to=512 512w,https://framerusercontent.com/images/M8JpKO7eycJP0DwKB0cgV1j8k8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/M8JpKO7eycJP0DwKB0cgV1j8k8.png 1368w\",style:{aspectRatio:\"1368 / 759\"},width:\"684\"}),/*#__PURE__*/e(\"p\",{children:\"When it has succeeded you will see this in top right.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"537\",src:\"https://framerusercontent.com/images/x0NZcZNDFIqMlpZ6NX4U0EBAg.png\",srcSet:\"https://framerusercontent.com/images/x0NZcZNDFIqMlpZ6NX4U0EBAg.png?scale-down-to=512 512w,https://framerusercontent.com/images/x0NZcZNDFIqMlpZ6NX4U0EBAg.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/x0NZcZNDFIqMlpZ6NX4U0EBAg.png 1919w\",style:{aspectRatio:\"1919 / 1075\"},width:\"959\"}),/*#__PURE__*/t(\"p\",{children:[\"And your training data now has a model number. Copy that whole id starting with \",/*#__PURE__*/e(\"code\",{children:\"ft:\"}),\" down to the last letter. You will need it soon.\"]}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Implementing the Chatbot\"}),/*#__PURE__*/t(\"p\",{children:[\"Once your fine-tuned model is ready, you can integrate it into your website. We are going to build a simple Flask application that demonstrates how to create a web-based chatbot interface. First, you will need to create a \",/*#__PURE__*/e(\"code\",{children:\"app.py\"}),\" file. Then create a templates folder, and within that folder create an index.html file.\"]}),/*#__PURE__*/e(\"p\",{children:\"my_flask_app/ \u251C\u2500\u2500 app.py \u2514\u2500\u2500 templates/ \u2514\u2500\u2500 index.html\"}),/*#__PURE__*/t(\"p\",{children:[\"Now within the \",/*#__PURE__*/e(\"code\",{children:\"app.py\"}),\" add the following code.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'from flask import Flask, request, jsonify, render_template\\nimport openai\\nimport config\\n\\napp = Flask(__name__)\\n\\nopenai.api_key = config.OPENAI_API_KEY\\n\\n@app.route(\"/\")\\ndef index():\\n    return render_template(\"index.html\")\\n\\n@app.route(\\'/chat\\', methods=[\\'POST\\'])\\ndef chat():\\n    user_input = request.json.get(\\'message\\')\\n    response = openai.chat.completions.create(\\n        model=\"ft:gpt-3.5-turbo-0125:riis-llc::XXXXXXXX\",\\n        messages=[{\\n            \"role\": \"user\",\\n            \"content\" : user_input\\n        }],\\n        max_tokens=150    \\n    )\\n    return jsonify({\\'response\\': response.choices[0].message.content})\\n\\nif __name__ == \\'__main__\\':\\n    app.run()',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Replace our model number here with your \",/*#__PURE__*/e(\"code\",{children:\"ft:\"}),\" string.\"]}),/*#__PURE__*/e(\"p\",{children:\"This Flask application serves an HTML page with a simple chat interface and handles API requests to your fine-tuned model.\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h2\",{children:\"HTML Template\"}),/*#__PURE__*/t(\"p\",{children:[\"Here\u2019s a basic HTML template for the chat interface that you can place in your \",/*#__PURE__*/e(\"code\",{children:\"index.html\"}),\" file.:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"<!DOCTYPE html>\\n\t<html>\\n\t\t\t<head>    \\n\t\t\t\t\t<title>Chatbot</title>\\n\t\t\t</head>\\n\t\t\t<body>    \\n\t\t\t\t\t<h1>Chat with our bot</h1>    \\n\t\t\t\t\t<div id=\\\"chatbox\\\"></div>    \\n\t\t\t\t\t<input type=\\\"text\\\" id=\\\"userInput\\\" placeholder=\\\"Type a message...\\\" />    \\n\t\t\t\t\t<button onclick=\\\"sendMessage()\\\">Send</button>    \\n\t\t\t\\n\t\t\t\t\t<script>        \\n\t\t\t\t\t\t\tfunction sendMessage() {\\n\t\t\t            var userInput = document.getElementById('userInput').value;\\n\t\t\t\t\t            fetch('/chat', {\\n\t\t\t\t\t\t              method: 'POST',                \\n\t\t\t\t\t\t              headers: {\\n\t\t\t\t\t                    'Content-Type': 'application/json',                \\n\t\t\t\t\t                },                \\n\t\t\t\t\t                body: JSON.stringify({message: userInput}),            \\n\t\t\t\t\t            })\\n\t\t\t\t\t            .then(response => response.json())\\n\t\t\t\t\t            .then(data => {\\n\t\t\t\t\t                var chatbox = document.getElementById('chatbox');                \\n\t\t\t\t\t                chatbox.innerHTML += `<p><strong>You:</strong> ${userInput}</p>`;                \\n\t\t\t\t\t                chatbox.innerHTML += `<p><strong>Bot:</strong> ${data.response}</p>`;                \\n\t\t\t\t\t                document.getElementById('userInput').value = '';            \\n\t\t\t\t\t            });        \\n\t\t\t\t\t         }\\n\t\t\t\t  </script>\\n\t\t\t</body>\\n\t</html>\",language:\"HTML\"})})}),/*#__PURE__*/e(\"p\",{children:\"Now when you run app.py in the console. It will give you an IP address which you can copy into the browser. You should see something like this:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"93\",src:\"https://framerusercontent.com/images/TuTN0apL5eq9J1EUR1EO2kkRin4.png\",srcSet:\"https://framerusercontent.com/images/TuTN0apL5eq9J1EUR1EO2kkRin4.png?scale-down-to=512 512w,https://framerusercontent.com/images/TuTN0apL5eq9J1EUR1EO2kkRin4.png 873w\",style:{aspectRatio:\"873 / 187\"},width:\"436\"}),/*#__PURE__*/e(\"p\",{children:\"Start asking away!\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Best Practices and Considerations\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Data Quality\"}),\": Ensure your training data is high-quality, diverse, and representative of the queries your chatbot will encounter.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Regular Updates\"}),\": Periodically update your training data and retrain your model to keep it current with new information or changes in your business.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Monitoring and Feedback\"}),\": Implement a system to monitor your chatbot\u2019s performance and collect user feedback for continuous improvement.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Fallback Mechanisms\"}),\": Have a plan for handling queries that fall outside your chatbot\u2019s knowledge domain, such as redirecting to human support.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Ethical Considerations\"}),\": Be transparent about the use of AI in your chatbot and ensure it adheres to ethical guidelines and privacy regulations.\"]})})]}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Conclusion\"}),/*#__PURE__*/e(\"p\",{children:\"Creating a customized website chatbot using ChatGPT and fine-tuning techniques allows you to provide personalized, efficient support to your website visitors. By following the steps outlined in this article, you can develop a chatbot that accurately represents your brand and effectively addresses your customers\u2019 needs.\"}),/*#__PURE__*/e(\"p\",{children:\"Remember that building an effective chatbot is an iterative process. Continuously gather feedback, analyze performance, and refine your model to ensure it provides the best possible user experience. With dedication and ongoing improvement, your customized chatbot can become a valuable asset for your website and business.\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/t(\"h3\",{children:[\"If you're interested in building more AI applications like this one, be sure to join \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/practical-chatgpt-api-programming/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!0,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"The OpenAI Applications Explorers Meetup\"})}),\".\"]})]});export const richText3=/*#__PURE__*/t(i.Fragment,{children:[/*#__PURE__*/e(\"p\",{children:\"If you\u2019ve landed here, chances are you know that MAVLink is the most widely used drone communication protocol outside of DJI. The MAVSDK provides collection of libraries designed to interface with MAVLink systems such as drones, cameras, or ground control systems (GCS). It provides a simple API for managing one or more vehicles, offering programmatic access to vehicle information, telemetry, and control over missions, movement, and other operations. Quite simply, you can use it to build apps to control your drone (and other cool autonomous systems). At a recent gathering of the Drone Software Meetup Group, Godfrey Nolan, President of RIIS LLC. showed attendees how to get started with the MAVSDK on Android. Feel free to follow along with the video or read the blog below to jump start your MAVSDK development. This post includes both a \u201CStupid Simple Example\u201D as well as a more hand\u2019s on tutorial if you want to roll up your sleeves and get your hands dirty.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{\"--aspect-ratio\":\"560 / 315\",aspectRatio:\"560 / 315\",height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js:Youtube\",children:t=>/*#__PURE__*/e(r,{...t,play:\"Off\",shouldMute:!0,thumbnail:\"Medium Quality\",url:\"https://www.youtube.com/embed/iu6kd8RGPE4?si=3fyN2y5x7wq5WLtb\"})})}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"403\",src:\"https://framerusercontent.com/images/kCNuhJBue7SEXIPqWDUEwUiJvQ.png\",srcSet:\"https://framerusercontent.com/images/kCNuhJBue7SEXIPqWDUEwUiJvQ.png?scale-down-to=512 512w,https://framerusercontent.com/images/kCNuhJBue7SEXIPqWDUEwUiJvQ.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/kCNuhJBue7SEXIPqWDUEwUiJvQ.png 1445w\",style:{aspectRatio:\"1445 / 806\"},width:\"722\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Stupid Simple Setup\"}),/*#__PURE__*/e(\"p\",{children:\"For our Stupid Simple Example, we will be using Java for a Software in the Loop (SITL) simulation. By coding with the MAVSDK we are skipping over QGroundControl (QGC). Although QGC has a lot of benefits and a great suite of tools, it\u2019s a whole other tutorial, and we want to keep things simple. For our example we will be using PX4, but Ardupilot can also be used.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"403\",src:\"https://framerusercontent.com/images/9smsdP6t6ETpcymmEi0dejD4.png\",srcSet:\"https://framerusercontent.com/images/9smsdP6t6ETpcymmEi0dejD4.png?scale-down-to=512 512w,https://framerusercontent.com/images/9smsdP6t6ETpcymmEi0dejD4.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/9smsdP6t6ETpcymmEi0dejD4.png 1447w\",style:{aspectRatio:\"1447 / 806\"},width:\"723\"}),/*#__PURE__*/e(\"p\",{children:\"The SITL setup doesn\u2019t require much in terms of hardware. In fact, this is a pretty bare bones setup for this tutorial.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"403\",src:\"https://framerusercontent.com/images/f8Vk3yqMRYRN2SpNaLUGKQnwdH4.png\",srcSet:\"https://framerusercontent.com/images/f8Vk3yqMRYRN2SpNaLUGKQnwdH4.png?scale-down-to=512 512w,https://framerusercontent.com/images/f8Vk3yqMRYRN2SpNaLUGKQnwdH4.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/f8Vk3yqMRYRN2SpNaLUGKQnwdH4.png 1447w\",style:{aspectRatio:\"1447 / 807\"},width:\"723\"}),/*#__PURE__*/e(\"p\",{children:\"However, you do need to follow several steps to ensure that your development environment is correctly configured.\"}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"strong\",{children:\"Prerequisites\"})}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Docker\"}),\": Ensure Docker is installed on your machine. Docker will be used to run the headless simulator.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Android Studio\"}),\": Install Android Studio for developing the Android client.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"MAVSDK-Java\"}),\": Clone the MAVSDK-Java repository from GitHub.\"]})})]}),/*#__PURE__*/e(\"h2\",{children:/*#__PURE__*/e(\"strong\",{children:\"Step-by-Step Setup\"})}),/*#__PURE__*/e(\"h3\",{children:/*#__PURE__*/e(\"strong\",{children:\"1. Clone the MAVSDK-Java Repository\"})}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"git clone https://github.com/mavlink/MAVSDK-Java.git\\ncd MAVSDK-Java\",language:\"Shell\"})})}),/*#__PURE__*/e(\"h3\",{children:\"2. Set up Docker\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"docker run --rm -it -p 8554:8554 jonasvautherin/px4-gazebo-headless:1.13.2 -v typhoon_h480<PHONE_IP><COMPUTER_IP>\",language:\"Shell\"})})}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"em\",{children:\"Special thanks to Jonas Vautherin, Software Engineer, Auterion for providing this ^^\"})}),/*#__PURE__*/e(\"h3\",{children:\"3. Edit MapsActivity.java\"}),/*#__PURE__*/e(\"p\",{children:\"Open the android-client in the examples folder in Android Studio. Also, make sure your Android Gradle Plugin version is 4.0.1 and your Gradle Version is 6.5.\"}),/*#__PURE__*/e(\"p\",{children:\"Look for the runMavsdkServer().\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"356\",src:\"https://framerusercontent.com/images/i0YqxfaIDgC2afNKy6CrP0n8.png\",srcSet:\"https://framerusercontent.com/images/i0YqxfaIDgC2afNKy6CrP0n8.png?scale-down-to=512 512w,https://framerusercontent.com/images/i0YqxfaIDgC2afNKy6CrP0n8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/i0YqxfaIDgC2afNKy6CrP0n8.png 1496w\",style:{aspectRatio:\"1496 / 712\"},width:\"748\"}),/*#__PURE__*/e(\"p\",{children:\"Then change this:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"int mavsdkServerPort=mavskdServer.run();\",language:\"Java\"})})}),/*#__PURE__*/e(\"p\",{children:\"To this:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'int mavsdkServerPort=mavskdServer.run(\"udp://14550\");',language:\"Java\"})})}),/*#__PURE__*/e(\"p\",{children:\"If you were paying attention to the SITL diagram earlier you will notice that the port we are running the mavSDKServer on is the one that points to the GCS.\"}),/*#__PURE__*/e(\"h2\",{children:\"Sample Client\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"406\",src:\"https://framerusercontent.com/images/HfmsjpwmDVdPDBqdTZSX9lA55Is.png\",srcSet:\"https://framerusercontent.com/images/HfmsjpwmDVdPDBqdTZSX9lA55Is.png?scale-down-to=512 512w,https://framerusercontent.com/images/HfmsjpwmDVdPDBqdTZSX9lA55Is.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/HfmsjpwmDVdPDBqdTZSX9lA55Is.png 1450w\",style:{aspectRatio:\"1450 / 812\"},width:\"725\"}),/*#__PURE__*/e(\"p\",{children:\"Make sure your phone is running is connected to your computer via USB and set to debug mode, then hit the play button in Android Studio to see what happens.\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"A More Hand\u2019s On Example\"}),/*#__PURE__*/e(\"h2\",{children:\"A 2-Minute Crash Course on Android Development\"}),/*#__PURE__*/t(\"p\",{children:[\"For an Android app you need a layout file, \",/*#__PURE__*/e(\"code\",{children:\"activity_main.xml\"}),\" and you need a main activity file, \",/*#__PURE__*/e(\"code\",{children:\"MainActivity.java\"}),\". Your layout is controlled by layout a file, and the main activity file is were things get done, like buttons, functions etc.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"405\",src:\"https://framerusercontent.com/images/wbmAwRAcl1BUvkmgrDo9lM2iz0.png\",srcSet:\"https://framerusercontent.com/images/wbmAwRAcl1BUvkmgrDo9lM2iz0.png?scale-down-to=512 512w,https://framerusercontent.com/images/wbmAwRAcl1BUvkmgrDo9lM2iz0.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/wbmAwRAcl1BUvkmgrDo9lM2iz0.png 1456w\",style:{aspectRatio:\"1456 / 810\"},width:\"728\"}),/*#__PURE__*/e(\"h2\",{children:\"Creating a Layout\"}),/*#__PURE__*/t(\"p\",{children:[\"For simplicities sake, we are only trying to do three things, connect to the server, take off, and land, so we need to build a layout within \",/*#__PURE__*/e(\"code\",{children:\"activity_main.xml\"}),\" that includes three buttons, one for each of those functions.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\\n    android:layout_width=\"match_parent\"\\n    android:layout_height=\"match_parent\"\\n    android:padding=\"16dp\">\\n\\n    <Button\\n        android:id=\"@+id/btn_server\"\\n        android:layout_width=\"wrap_content\"\\n        android:layout_height=\"wrap_content\"\\n        android:text=\"MAVSDK Server\" />\\n\\n    <Button\\n        android:id=\"@+id/btn_takeoff\"\\n        android:layout_width=\"wrap_content\"\\n        android:layout_height=\"wrap_content\"\\n        android:text=\"Take Off\"\\n        android:layout_below=\"@id/btn_server\" \\n        android:layout_marginTop=\"16dp\" />\\n\\n    <Button\\n        android:id=\"@+id/btn_land\"\\n        android:layout_width=\"wrap_content\"\\n        android:layout_height=\"wrap_content\"\\n        android:text=\"Land\"\\n        android:layout_below=\"@id/btn_takeoff\" \\n        android:layout_marginTop=\"16dp\"/>\\n\\n</RelativeLayout>',language:\"HTML\"})})}),/*#__PURE__*/e(\"h2\",{children:\"Writing the Functions and Listeners in MainActivity.java\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'\\n    @Override\\n    protected void onCreate(Bundle savedInstanceState) {\\n        super.onCreate(savedInstanceState);\\n        setContentView(R.layout.activity_main);\\n\\n        btnServer = findViewById(R.id.btn_server);\\n        btnTakeoff = findViewById(R.id.btn_takeoff);\\n        btnLand = findViewById(R.id.btn_land);\\n\\n        btnServer.setOnClickListener(v -> initializeServerAndDrone());\\n        btnTakeoff.setOnClickListener(v -> takeOff());\\n        btnLand.setOnClickListener(v -> land());\\n    }\\n\\n    private void initializeServerAndDrone() {\\n        mavsdkServer = new MavsdkServer();\\n        int mavsdkServerPort = mMavsdkServer.run(\"udp://:14540\");\\n        mDrone = new System(MAVSDK_SERVER_IP, mavsdkServerPort);\\n    }\\n\\n    private void takeOff() {\\n        mDrone.getAction.arm().andThen(mDrone.getAction().takeoff()).subscribe();\\n    }\\n\\n    private void land() {\\n        mDrone.getAction().arm().andThen(mDrone.getAction().land()).subscribe();\\n    }\\n\\n}',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"In \",/*#__PURE__*/e(\"code\",{children:\"MainActivity.java\"}),\" add the below code within the \",/*#__PURE__*/e(\"code\",{children:\"MainActivity\"}),\" class.\"]}),/*#__PURE__*/t(\"p\",{children:[\"What we are doing here is really simple. We create the \",/*#__PURE__*/e(\"code\",{children:\"btn\"}),\" variables and connect them to our layout buttons by using the findViewById method. Then we add listeners to each of those variables which will invoke the functions at the bottom of the code for each of the corresponding buttons.\"]}),/*#__PURE__*/e(\"p\",{children:\"Let\u2019s breakdown the functions more.\"}),/*#__PURE__*/e(\"h3\",{children:\"initializeServerAndDrone()\"}),/*#__PURE__*/t(\"p\",{children:[\"The first line creates a new instance of the\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"MavsdkServer\"})}),\"\\xa0class, which is responsible for handling the communication between the application and the drone. Then we bind the server to the UDP port. Lastly we create a new System object which represents the drone.\"]}),/*#__PURE__*/e(\"h3\",{children:\"takeoff()\"}),/*#__PURE__*/e(\"p\",{children:\"This arms the drone, issues a takeoff command and then subscribes to the observable stream created by the chained commands.\"}),/*#__PURE__*/e(\"h3\",{children:\"land()\"}),/*#__PURE__*/e(\"p\",{children:\"Land functions similarly except it issues a land command.\"}),/*#__PURE__*/e(\"h2\",{children:\"Updating the Dependencies\"}),/*#__PURE__*/t(\"p\",{children:[\"Add the following changes within dependencies{}{ in the \",/*#__PURE__*/e(\"code\",{children:\"build.gradle\"}),\" file:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"dependencies {\\n    implementation 'io.mavsdk:mavsdk'\\n    implementation 'io.mavsdk:mavsdk-server'\\n}\",language:\"Java\"})})}),/*#__PURE__*/e(\"h2\",{children:\"Run the App for the First Time\"}),/*#__PURE__*/t(\"p\",{children:[\"In the terminal run \",/*#__PURE__*/e(\"code\",{children:\"docker run --rm -it jonasvautherin/px4-gazebo-headless:1.11.0\"}),\".\"]}),/*#__PURE__*/e(\"p\",{children:\"Make sure your Android device is connected via USB with debugging enabled. Run the app on the device and it should connect to the simulator on your machine.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"151\",src:\"https://framerusercontent.com/images/9RkKRWu6t5adUKhidM3l19Mxp8.png\",srcSet:\"https://framerusercontent.com/images/9RkKRWu6t5adUKhidM3l19Mxp8.png?scale-down-to=512 512w,https://framerusercontent.com/images/9RkKRWu6t5adUKhidM3l19Mxp8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/9RkKRWu6t5adUKhidM3l19Mxp8.png 1456w\",style:{aspectRatio:\"1456 / 302\"},width:\"728\"}),/*#__PURE__*/e(\"h2\",{children:\"Take Off!\"}),/*#__PURE__*/e(\"p\",{children:\"Hit the Take off button in the app on the Android device and you should see this in the command line:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"106\",src:\"https://framerusercontent.com/images/9sL6NHcr8BZw7umbTY8NuC7E.png\",srcSet:\"https://framerusercontent.com/images/9sL6NHcr8BZw7umbTY8NuC7E.png?scale-down-to=512 512w,https://framerusercontent.com/images/9sL6NHcr8BZw7umbTY8NuC7E.png 1008w\",style:{aspectRatio:\"1008 / 213\"},width:\"504\"}),/*#__PURE__*/e(\"p\",{children:\"All the log info here is from the thread you subscribed to in the takeoff().\"}),/*#__PURE__*/e(\"h2\",{children:\"Landing!\"}),/*#__PURE__*/e(\"p\",{children:\"Hitting the landing button should give you this set of logs:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"126\",src:\"https://framerusercontent.com/images/by7AHAVSH4PSzLELreU2NSXEYpc.png\",srcSet:\"https://framerusercontent.com/images/by7AHAVSH4PSzLELreU2NSXEYpc.png?scale-down-to=512 512w,https://framerusercontent.com/images/by7AHAVSH4PSzLELreU2NSXEYpc.png 1007w\",style:{aspectRatio:\"1007 / 253\"},width:\"503\"}),/*#__PURE__*/e(\"h2\",{children:\"What Next?\"}),/*#__PURE__*/e(\"p\",{children:\"We can make drone go up and make drone go down, but what if we want to do something more interesting or useful. In order to make a drone do anything interesting we will need telemetry information. Here is a non-comprehensive list of the telemetry data you can receive from the drone.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"405\",src:\"https://framerusercontent.com/images/PwNTXvqlzebnHTfpVbg7fG0.png\",srcSet:\"https://framerusercontent.com/images/PwNTXvqlzebnHTfpVbg7fG0.png?scale-down-to=512 512w,https://framerusercontent.com/images/PwNTXvqlzebnHTfpVbg7fG0.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/PwNTXvqlzebnHTfpVbg7fG0.png 1445w\",style:{aspectRatio:\"1445 / 810\"},width:\"722\"}),/*#__PURE__*/e(\"p\",{children:\"Why don\u2019t we start by getting some altitude data. Add this code to MainActivity.java:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'private void getAltitude() {\\n\t// get the altitude of the drone\\n\tFlowable<Float> altitude = mDrone.getTelemetry().getPosition().map(new Function<Telemetry.Position position) throws Exception {\\n\t\treturn position.getRelativeAltitudeM();\\n\t}\\n});\\n// subscribe to the altitude flowable\\n\taltitude.subscribeOn(Schedulers.io())\\n\t\t.observeOn(Schedulers.single())\\n\t\t.subscribe(new io.reactivex.functions.Consumer<Float>() {\\n\t\t\t@Override\\n\t\t\tpublic void accept(Float aFloat) throws Exception {\\n\t\t\t\tLog.d(\"Altitude\", \"Altitude: \" + aFloat);\\n\t\t\t}\\n\t\t});\t\t\\n}',language:\"Java\"})})}),/*#__PURE__*/t(\"p\",{children:[\"This code is using RxJava to retrieve the altitude of a drone from its telemetry data in a reactive way. \",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"mDrone.getTelemetry().getPosition()\"})}),\"\\xa0returns a\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Flowable\"})}),\"\\xa0that emits\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Telemetry.Position\"})}),\"\\xa0objects containing the drone's position data. The\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"map\"})}),\"\\xa0operator is used to transform each\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Telemetry.Position\"})}),\"\\xa0object into a\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Float\"})}),\"\\xa0representing the relative altitude in meters, using the provided lambda function:\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"position -> position.getRelativeAltitudeM()\"})}),/*#__PURE__*/e(\"strong\",{children:\" Then t\"}),\"he\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"subscribeOn\"})}),\"\\xa0operator is used to specify the Scheduler on which the source\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Flowable\"})}),\"\\xa0should execute its work while the he\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"observeOn\"})}),\"\\xa0operator is used to specify the Scheduler on which the downstream operators (after\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"observeOn\"})}),\") execute.\"]}),/*#__PURE__*/t(\"p\",{children:[\"More simply, this code retrieves the drone's position data from the telemetry on the IO Scheduler thread pool, transforms each position object into a\\xa0\",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(\"strong\",{children:\"Float\"})}),\"\\xa0representing the relative altitude, and emits the altitude values on a single-threaded Scheduler. Essentially, we are logging whatever altitude data comes streaming in.\"]}),/*#__PURE__*/e(\"h3\",{children:\"Adding Latitude and Longitude\"}),/*#__PURE__*/e(\"p\",{children:\"Going up and down is nice, but it might be useful to go North, South, East, and West also. Let\u2019s add some Latitude and Longitude data to get a better idea of our drone\u2019s position in the world.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'private void getLatitudeLongitude() {\\n\t// get the latitude and longitude of the drone\\n\tFlowable<Telemetry.Position> position = mDrone.getTelemetry().getPosition();\\n\t// subscribe to the position flowable\\n\tposition.subscribeOn(Schedulers.io())\\n\t\t.observeOn(Schedulers.single())\\n\t\t.subscribe(new io.reactivex.functions.Consumer<Telemetry.Position>() {\\n\t\t\t@Override\\n\t\t\tpublic void accept(Telemetry.Position position) throws Exception {\\n\t\t\t\tLog.d(\"Position\", \"Latitude: \" + position.getLatitudeDeg() + \" Longitude: \" + position.getLongitudeDef());\\n\t\t\t}\\n\t\t});\\n}',language:\"Java\"})})}),/*#__PURE__*/e(\"p\",{children:\"This is very similar to our getAltitude() with but with an important key difference. Here we are no longer transforming the position data into a float.\"}),/*#__PURE__*/t(\"p\",{children:[\"Before moving on, if you haven\u2019t already, be sure to add Get Altitude and Get Position buttons to the \",/*#__PURE__*/e(\"code\",{children:\"activity_main.xml\"}),\" file.\"]}),/*#__PURE__*/e(\"p\",{children:\"Now if you hit the Get Position button you should see Latitude and Longitude data in the console.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"103\",src:\"https://framerusercontent.com/images/xLvK3XKJO86410K0OrTqNk9X0k.png\",srcSet:\"https://framerusercontent.com/images/xLvK3XKJO86410K0OrTqNk9X0k.png?scale-down-to=512 512w,https://framerusercontent.com/images/xLvK3XKJO86410K0OrTqNk9X0k.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/xLvK3XKJO86410K0OrTqNk9X0k.png 1457w\",style:{aspectRatio:\"1457 / 207\"},width:\"728\"}),/*#__PURE__*/e(\"h2\",{children:\"Creating a Simple Mission\"}),/*#__PURE__*/t(\"p\",{children:[\"First, add a \u2018Start orbit flight\u2019 button within \",/*#__PURE__*/e(\"code\",{children:\"activity_main.xml\"}),\".\"]}),/*#__PURE__*/t(\"p\",{children:[\"Then add the following code to \",/*#__PURE__*/e(\"code\",{children:\"MainActivity.java\"}),\":\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"private void createOrbitFlight() {\\n\tMission.MissionItem missionItem = new Mission.MissionItem(\\n\t\t47.39803985999999997,\\n\t\t8.545572540000000002,\\n\t\t10F,\\n\t\t10F,\\n\t\ttrue,\\n\t\tFloat.NaN,\\n\t\tFloat.NaN,\\n\t\tMission.MissionItem.CameraAction.NONE,\\n\t\tFloat.NaN,\\n\t\tDouble.NaN,\\n\t\t10F,\\n\t\tFloat.NaN,\\n\t\tFloat.NaN\\n\t);\\n\tList<Mission.MissionItem> missionItems = Collections.singletonList(missionItem);\\n\tMission.MissionPlan missionPlan = new Mission.MissionPlan(missionItems);\\n\t\\n\tmDrone.getMission().setReturToLaunchAfterMission(true);\\n\tmDrone.getMission().uploadMission(missionPlan)\\n\t\t.andThen(mDrone.getMission().startMisssion())\\n\t\t.subscribe();\\n}\",language:\"Java\"})})}),/*#__PURE__*/e(\"p\",{children:\"We\u2019ve prefilled our mission with some data, but what does it all mean. The first two numbers are our latitude and longitude. The first 10F is our relative altitude and our second 10F is our speed. The true sets isFlyThrough to on. The last 10F is a relative radius to make sure the drone orbits.\"}),/*#__PURE__*/e(\"p\",{children:\"This whole list is actually just one mission item.\"}),/*#__PURE__*/t(\"p\",{children:[\"After the mission is over we have the drone return to its launch position with \",/*#__PURE__*/e(\"code\",{children:\"mDrone.getMission().setReturToLaunchAfterMission(true);\"}),\" and then we upload the mission and reset the drone\u2019s mission status.\"]}),/*#__PURE__*/e(\"p\",{children:\"Hit the Play button in Android Studio to build and run.\"}),/*#__PURE__*/e(\"p\",{children:\"Assuming this works you should see logs like this in the console.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"101\",src:\"https://framerusercontent.com/images/vROsF4esae1CZ3yZMDSOWDpnQ.png\",srcSet:\"https://framerusercontent.com/images/vROsF4esae1CZ3yZMDSOWDpnQ.png?scale-down-to=512 512w,https://framerusercontent.com/images/vROsF4esae1CZ3yZMDSOWDpnQ.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/vROsF4esae1CZ3yZMDSOWDpnQ.png 1384w\",style:{aspectRatio:\"1384 / 202\"},width:\"692\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/e(\"h1\",{children:\"Final Thoughts\"}),/*#__PURE__*/e(\"p\",{children:\"By following this comprehensive tutorial, you should now have the skills to develop Android applications that can interface with and control drones and other autonomous systems using the MAVSDK (MAVLink Software Development Kit). You learned how to set up the required development environment, including installing Docker, Android Studio, and cloning the MAVSDK-Java repository. The tutorial guided you through creating a basic Android app with user interface elements like buttons to connect to a simulated drone server, arm the drone, initiate takeoff and landing commands, and subscribe to telemetry data streams like altitude, latitude, and longitude using RxJava. You gained hands-on experience creating a simple missions and you are now equipped to build more advanced drone applications leveraging the MAVSDK's awesome capabilities.\"}),/*#__PURE__*/t(\"h3\",{children:[\"If you want to learn more about drone development, be sure to join the \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/drone-software-meetup-group/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"Drone Software Meetup Group\"})}),\", where you can find more cool projects like this one every month.\"]})]});export const richText4=/*#__PURE__*/t(i.Fragment,{children:[/*#__PURE__*/t(\"p\",{children:[\"By now ChatGPT needs no introduction, but most people are only familiar with the front end \u2018chat\u2019 interface. In the first edition of the \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/practical-chatgpt-api-programming/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"OpenAI Application Explorers meetup\"})}),\", Godfrey Nolan, President, RIIS LLC., demonstrated how with a little extra effort you can utilize the ChatGPT API to create whole AI-driven applications. In this tutorial, we are going to show you how to build a classic \",/*#__PURE__*/e(\"strong\",{children:\"Choose Your Own Adventure\"}),\" game from scratch using ChatGPT and a little Python. If you are not familiar with programming, don\u2019t fret, this tutorial is meant for beginners, and if you ever feel lost, you can always ask ChatGPT for clarity. You can follow along with the video from the Meetup or read the tutorial below.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{\"--aspect-ratio\":\"560 / 315\",aspectRatio:\"560 / 315\",height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:NEd4VmDdsxM3StIUbddO/1de6WpgIbCrKkRcPfQcW/YouTube.js:Youtube\",children:t=>/*#__PURE__*/e(r,{...t,play:\"Off\",shouldMute:!0,thumbnail:\"Medium Quality\",url:\"https://www.youtube.com/watch?v=-X2ixADLxB4\"})})}),/*#__PURE__*/e(\"h1\",{children:\"Part 1: Calling a Chat Completion and Image Creation with Python\"}),/*#__PURE__*/e(\"h2\",{children:\"Creating an OpenAI account\"}),/*#__PURE__*/t(\"p\",{children:[\"If you haven\u2019t set one up already, you should create an account with OpenAI. Navigate to \",/*#__PURE__*/e(o,{href:\"http://platform.openai.com/playground/chat\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"platform.openai.com/playground/chat\"})}),\" and you will see a very different interface for ChatGPT than what you are used to. This is the playground and it is an awesome test environment where you can experiment with OpenAI's language models, including GPT-4o. It provides a user-friendly interface to test and fine-tune your prompts, see how different models respond, and explore various settings and parameters.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"725\",src:\"https://framerusercontent.com/images/Yhyxme7CxykTz6FWFmWqkp4dV2s.png\",srcSet:\"https://framerusercontent.com/images/Yhyxme7CxykTz6FWFmWqkp4dV2s.png?scale-down-to=512 512w,https://framerusercontent.com/images/Yhyxme7CxykTz6FWFmWqkp4dV2s.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/Yhyxme7CxykTz6FWFmWqkp4dV2s.png?scale-down-to=2048 2048w,https://framerusercontent.com/images/Yhyxme7CxykTz6FWFmWqkp4dV2s.png 2544w\",style:{aspectRatio:\"2544 / 1451\"},width:\"1272\"}),/*#__PURE__*/e(\"p\",{children:\"You will notice the green system box at the top. Here, you can provide system-level instructions to guide the behavior of the model. This helps in setting the context and tone for the responses. For example, you can instruct the model to act as a helpful assistant or to follow specific conversational rules. If you\u2019ve created a custom GPT before, this is a similar but more direct way to set the boundaries for how the app should behave.\"}),/*#__PURE__*/e(\"p\",{children:\"You will also notice some additional controls on the side. These all help you dial in the variability of ChatGPTs response, but for now, don\u2019t worry about it.\"}),/*#__PURE__*/e(\"p\",{children:\"Let\u2019s start playing around. Down at the bottom, type in \u201CWhat is a choose your own adventure game?\u201D into the Enter user message text box. Hit CTRL or CMD Enter to submit your prompt.\"}),/*#__PURE__*/e(\"p\",{children:\"In the top right corner, you will see a </> icon. Click on that and you will see the code behind your prompt submission. It\u2019s just an extremely simple API call.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"693\",src:\"https://framerusercontent.com/images/mvGv078RC8KD8nimL4zr1v0wAaw.png\",srcSet:\"https://framerusercontent.com/images/mvGv078RC8KD8nimL4zr1v0wAaw.png?scale-down-to=512 512w,https://framerusercontent.com/images/mvGv078RC8KD8nimL4zr1v0wAaw.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/mvGv078RC8KD8nimL4zr1v0wAaw.png?scale-down-to=2048 2048w,https://framerusercontent.com/images/mvGv078RC8KD8nimL4zr1v0wAaw.png 2556w\",style:{aspectRatio:\"2556 / 1386\"},width:\"1278\"}),/*#__PURE__*/e(\"p\",{children:\"You will notice that for every variable in the call, there is a corresponding variable you can control via the GUI in the playground. That\u2019s it. There is not a lot of magic.\"}),/*#__PURE__*/e(\"h1\",{children:/*#__PURE__*/e(\"strong\",{children:\"Setting Up Your API Keys\"})}),/*#__PURE__*/e(\"p\",{children:\"Now that we know what an API call looks like, we are going to have to set up our API keys. OpenAI is going to milk you $$$$ to get started, but thankfully that will get you pretty far while testing.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"359\",src:\"https://framerusercontent.com/images/bS1Z6Vw9i8LVLKkJw8hLizC2II.png\",srcSet:\"https://framerusercontent.com/images/bS1Z6Vw9i8LVLKkJw8hLizC2II.png?scale-down-to=512 512w,https://framerusercontent.com/images/bS1Z6Vw9i8LVLKkJw8hLizC2II.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/bS1Z6Vw9i8LVLKkJw8hLizC2II.png 1291w\",style:{aspectRatio:\"1291 / 719\"},width:\"645\"}),/*#__PURE__*/e(\"p\",{children:\"To use the OpenAI API, you need to set up your API keys. Here\u2019s how you can do it:\"}),/*#__PURE__*/t(\"ol\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Navigate to the API Section\"}),\": After logging in, navigate to the API section on the OpenAI dashboard.\"]})}),/*#__PURE__*/t(\"li\",{\"data-preset-tag\":\"p\",children:[/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Generate a New API Key\"}),\":\"]}),/*#__PURE__*/t(\"ul\",{children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:'Click on \"Create new secret key\".'})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Name your key and set the permissions (e.g., read-only, full access).\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:'Click \"Create secret key\" and copy the key. Make sure to store it securely as you won\u2019t be able to view it again.'})})]})]}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Set Up Billing\"}),\": If you haven\u2019t already, set up a payment method for billing. This is necessary to use the API.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Save Your API Key\"}),\": Store your API key in a secure place, such as an environment variable or a configuration file that is not included in your source code repository.\"]})})]}),/*#__PURE__*/e(\"h1\",{children:\"Getting Ready to Code\"}),/*#__PURE__*/e(\"h2\",{children:\"VSCode\"}),/*#__PURE__*/t(\"p\",{children:[\"Technically, you can write all the code you need using Notepad or a text editor, but it\u2019s 2024 and there are better environments to code in. We recommend using VSCode, which also has Github CoPilot integration. You can download it at \",/*#__PURE__*/e(o,{href:\"http://code.visualstudio.com/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"code.visualstudio.com\"})}),\".\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"269\",src:\"https://framerusercontent.com/images/yUKre2mxxeG5egl2E0diauftNV8.png\",srcSet:\"https://framerusercontent.com/images/yUKre2mxxeG5egl2E0diauftNV8.png?scale-down-to=512 512w,https://framerusercontent.com/images/yUKre2mxxeG5egl2E0diauftNV8.png 902w\",style:{aspectRatio:\"902 / 539\"},width:\"451\"}),/*#__PURE__*/e(\"h2\",{children:\"Python\"}),/*#__PURE__*/t(\"p\",{children:[\"You want to make sure you are running the latest and greatest version of Python on your system. Python comes pre-installed on a lot of OS distributions these days, but rarely is it going to be the most up-to-date version. If you don't, you can always download it from\\xa0\",/*#__PURE__*/e(o,{href:\"https://www.python.org/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"python.org\"})}),\" and install it. If you are not sure exactly how to do this, now is great time to ask ChatGPT for an answer that is specific to your OS.\"]}),/*#__PURE__*/e(\"p\",{children:'Once you know you have the latest version of Python installed, open VSCode, go to the Extensions view by clicking the Extensions icon in the Activity Bar on the side of the window, and search for \"Python\". Install the extension provided by Microsoft.'}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"143\",src:\"https://framerusercontent.com/images/1aAGb7FpGXIlmy5vluUEBLp18e0.png\",style:{aspectRatio:\"293 / 287\"},width:\"146\"}),/*#__PURE__*/e(\"p\",{children:\"This will help with code completion, error detection and debugging.\"}),/*#__PURE__*/e(\"p\",{children:\"You will need to install two important python libraries using the pip command. Use the terminal function in VSCode and type in the following in your directory of choice:\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"code\",{children:\"pip install openai\"})}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"code\",{children:\"pip install config\"})}),/*#__PURE__*/t(\"p\",{children:[\"The \",/*#__PURE__*/e(\"code\",{children:\"openai\"}),\" library is obviously to use OpenAI functionality. \",/*#__PURE__*/e(\"code\",{children:\"config\"}),\" will be used to store our API keys so they aren\u2019t exposed to application users.\"]}),/*#__PURE__*/e(\"h2\",{children:\"Your First API Prompt Call\"}),/*#__PURE__*/t(\"p\",{children:[\"In your project folder create a config.py file. Create a variable \",/*#__PURE__*/e(\"code\",{children:\"OPENAI_API_KEY=\u201D\u201D\"}),\" and fill in the space between the quotation marks with your key from OpenAI.\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"61\",src:\"https://framerusercontent.com/images/Q26DgXshTD3k89D40PcneZOVGE.png\",srcSet:\"https://framerusercontent.com/images/Q26DgXshTD3k89D40PcneZOVGE.png?scale-down-to=512 512w,https://framerusercontent.com/images/Q26DgXshTD3k89D40PcneZOVGE.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/Q26DgXshTD3k89D40PcneZOVGE.png 1315w\",style:{aspectRatio:\"1315 / 123\"},width:\"657\"}),/*#__PURE__*/t(\"p\",{children:[\"Create a second file called \",/*#__PURE__*/e(o,{href:\"http://app.py/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"app.py\"})}),\". In it we will copy our code from the OpenAI playground dashboard from before. It should looks something like the following.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'from openai immport OpenAI\\nclient = OpenAI()\\n\\nresponse = clien.chat.completions.create(\\n\tmodel=\"gpt-4o\",\\n\tmessages=[],\\n\ttemperature=1,\\n\tmax_tokens=256\\n\ttop_p=1,\\n\tfrequency_penalty=0,\\n\tpresence_penalty=0\t\\n)',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Okay, but this won\u2019t do anything on it\u2019s own so we have to use our key stored in our config file to get things going. Also, while we are at it, we will fill the messages variable with information to get our first prompt response.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'from openai immport OpenAI\\nimport config\\n\\nclient = OpenAI(api_key=config.OPENAI_API_KEY)\\n\\nresponse = clien.chat.completions.create(\\n\tmodel=\"gpt-4o\",\\n\tmessages=[\\n\t\t\t\"role\": \"user\",\\n\t\t\t\"content\": \"What is a choose your own adventure game?\"\\n\t],\\n\ttemperature=1,\\n\tmax_tokens=256\\n\ttop_p=1,\\n\tfrequency_penalty=0,\\n\tpresence_penalty=0\t\\n)\\n\\nprint(response)',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Finally, we add the print() command to print our response from the API call to the console.\"}),/*#__PURE__*/t(\"p\",{children:[\"Run the command \",/*#__PURE__*/e(\"code\",{children:\"python .\\\\\\\\app.py\"}),\" from the terminal and you will be rewarded with your first ever API response from ChatGPT\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"334\",src:\"https://framerusercontent.com/images/122f1aqDwhQzUg3wgat00Umpvn8.png\",srcSet:\"https://framerusercontent.com/images/122f1aqDwhQzUg3wgat00Umpvn8.png?scale-down-to=512 512w,https://framerusercontent.com/images/122f1aqDwhQzUg3wgat00Umpvn8.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/122f1aqDwhQzUg3wgat00Umpvn8.png 1301w\",style:{aspectRatio:\"1301 / 669\"},width:\"650\"}),/*#__PURE__*/e(\"h2\",{children:\"Generating Images\"}),/*#__PURE__*/e(\"p\",{children:\"While the original choose your own adventure games were only text-based, we can go a step-further and add images to ours with the DALL-E API. Luckily, this is not all that different from our prompt call.\"}),/*#__PURE__*/t(\"p\",{children:[\"Comment out the first \",/*#__PURE__*/e(\"code\",{children:\"response\"}),\" variable and add the following in the app.py file :\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'response = client.images.generate(\\n\tmodel=\"dall-e-3\",\\n\tprompt=\"generate a picture that illustrates the concept of a choose your own adventure game\",\\n\tsize=\"1792x1024\",\\n\tquality=\"standard\",\\n\tn=1\\n)\\n\\nimage_url = response.data[0].url\\nprint(image_url)',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Execute the same \",/*#__PURE__*/e(\"code\",{children:\"python .\\\\\\\\app.py\"}),\" command as before in the terminal and you will get a block of text similar to this:\"]}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"99\",src:\"https://framerusercontent.com/images/Dje0rxU06nzWwSiGmEghJJt3WRo.png\",srcSet:\"https://framerusercontent.com/images/Dje0rxU06nzWwSiGmEghJJt3WRo.png?scale-down-to=512 512w,https://framerusercontent.com/images/Dje0rxU06nzWwSiGmEghJJt3WRo.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/Dje0rxU06nzWwSiGmEghJJt3WRo.png 1287w\",style:{aspectRatio:\"1287 / 198\"},width:\"643\"}),/*#__PURE__*/e(\"p\",{children:\"If you copy that into a browser, you should see something more like this:\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"363\",src:\"https://framerusercontent.com/images/MBXp5PaMsKTYTEMNXFCL0NcBYQ.png\",srcSet:\"https://framerusercontent.com/images/MBXp5PaMsKTYTEMNXFCL0NcBYQ.png?scale-down-to=512 512w,https://framerusercontent.com/images/MBXp5PaMsKTYTEMNXFCL0NcBYQ.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/MBXp5PaMsKTYTEMNXFCL0NcBYQ.png 1274w\",style:{aspectRatio:\"1274 / 727\"},width:\"637\"}),/*#__PURE__*/e(\"p\",{children:\"NICE!\"}),/*#__PURE__*/e(\"h1\",{children:\"Part 2: Creating a Choose Your Own Adventure Game\"}),/*#__PURE__*/e(\"h2\",{children:\"Setting up a Flask Template\"}),/*#__PURE__*/e(\"p\",{children:\"It\u2019s time to build an actual application. We chose the Flask framework for Python because it is one of the simplest ways to get an HTML-based app up and running for testing. To get started, you first have to install Flask for Python.\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"code\",{children:\"pip insall flask\"})}),/*#__PURE__*/t(\"p\",{children:[\"Next, we need to create an HTML skeleton to fit our API responses into. Create a folder in your project with the name \",/*#__PURE__*/e(\"code\",{children:\"templates\"}),\" then create file in the project folder called \",/*#__PURE__*/e(\"code\",{children:\"index.html\"}),\" with the following code:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'<!DOCTYPE html>\\n<html lang=\"en\">\\n<head>\\n\t<title>Button Choice</title>\\n</head>\\n<body>\\n\t<center>\\n\t\t<img src=\"{{ img_path }}\" alt=\"Choose Your Own Adventure\" width=\"448\" height=\"256\">\\n\t\t<h4>{{ story }}</h4>\\n\t\t<form action=\"/submit\" method=\"post\">\\n\t\t\t<button type=\"submit\" name=\"choice\" value=\" {{ button_name1 }} \">{{ button_name1 }}</button>\\n\t\t\t<button type=\"submit\" name=\"choice\" value=\" {{ button_name2 }} \">{{ button_name2 }}</button>\\n\t\t</form>\\n\t</center>\\n</body>\\n</html>',language:\"HTML\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Now we are going to make some heavy modifications to our \",/*#__PURE__*/e(\"code\",{children:\"app.py\"}),\" file. Comment out our Dall-E call and add this code:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"from flask import Flask, request, render_template\\n\\napp = Flask(__name__)\\n\\nimg ='{{Insert your image URL}}'\\n\\n@app.route('/')\\ndef index():\\n\timg_path=img\\n\tstory=\\\"Click on a button below to start your adventure!\\\"\\n\tbutton_name1 = \\\"A knight discovers a hidden enchanted castle\\\"\\n\tbutton_name2 = \\\"A scientist uncovers a portal to an alien world\\\"\\n\treturn render_template('index.html', button_name1=button_name1, button_name2=button_name2, img_path=img_path)\\n\\n@app.route('/submit', methods=['POST'])\\ndef submit():\\n\tchoice = request.form['choice']\\n\treturn f'You selected {choice}'\\n\t\\nif __name__ == '__main__':\\n\tapp.run(debug=True)\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Let\u2019s go line-by-line to describe what is happening here.\"}),/*#__PURE__*/e(\"p\",{children:\"First, we have our imports, which include the main Flask class, a request function for handling incoming http requests, and render_template, which is as the name says, for rendering templates.\"}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"code\",{children:\"app = Flask(**name**)\"}),\" creates an application instance\"]}),/*#__PURE__*/e(\"p\",{children:\"The img variable is self-explanatory.\"}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"code\",{children:\"@app.route('/')\"}),\" defines our route for the root URL\"]}),/*#__PURE__*/t(\"p\",{children:[\"The \",/*#__PURE__*/e(\"code\",{children:\"def index():\"}),\" loads the variables and then creates the page by passing the variables into the template.\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"code\",{children:\"@app.route('/submit', methods=['Post'])\"}),\" defines our route after a choice button has been pressed by the user.\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"code\",{children:\"def submit():\"}),\" creates a function and within it there\u2019s the choice variable, which will make a request based on the user\u2019s choice. The return line will return the string \u201CYou selected {choice}\u201D back to the client as an HTTP response.\"]}),/*#__PURE__*/e(\"p\",{children:\"The final if statement runs the application and checks if the script is being run directly (as opposed to being imported as a module).\"}),/*#__PURE__*/e(\"h2\",{children:\"Getting the OpenAI Content on the Page\"}),/*#__PURE__*/e(\"h3\",{children:\"Creating the Starting Image\"}),/*#__PURE__*/t(\"p\",{children:[\"Remember that Dall-E API call we made earlier? Let\u2019s change that into a function our app will call in our \",/*#__PURE__*/e(\"code\",{children:\"app.py\"}),\".\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'def generate_image(image_caption, dimensions=(1792, 1024):\\n\timage_response = client.images.generate(\\n\t\tmodel=\"dall-e-3\",\\n\t\tprompt=(image_caption[:1000]),\\n\t\tn=1,\\n\t\tsize=f\"{dimensions[0]x{dimensions[1]\\'\\n\t)\\n\treturn image_response.data[0].url',language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"You will also need to change \",/*#__PURE__*/e(\"code\",{children:\"img_path\"}),\" to this:\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'img_path=generate_image(\"Generate a picture that illustrates the concept of a choose your own adventure game\")',language:\"JSX\"})})}),/*#__PURE__*/e(\"h3\",{children:\"Constraining the Response\"}),/*#__PURE__*/e(\"p\",{children:\"You may be wondering at this point, why are we starting with the image rather than the text prompt. Well, the term prompt engineering is not just an overblown industry term. Even at low temperatures, ChatGPT can be very variable at formatting its response structure. If your format is not consistent, it can be nearly impossible to parse and get onto the page.\"}),/*#__PURE__*/e(\"p\",{children:\"To rectify this, you need an extremely large prompt like this.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"You, 'assistant', are telling me, 'user', an interactive choose-your-own-adventure story. Your reponses are with labels so I can parse them and display them in a user interface.\\nEach step of the story, you present the following information.\\nStory. The current state of the story.\\nCaption. A detailed aption showing the current state of the story to be used as a Dall-E image prompt. It should be as consistent as possible with the previous caption.\\nChoice1. The text of the first choice.\\nChoice2. The text of the second choice.\\nYour image captions should be concise but repeat specific details about the setting, characters, and objects in the story to help generate consistent images across repeated invocations.\\nPresent exactly two choices to the user. Never offer blank (empty) choices.\\nOnly present choices that build on the story. Do not present choice that lead the main character awya from actioin or conflict (such as \\\"going home\\\").\\nDo not repeat yourself.\",language:\"Markdown\"})})}),/*#__PURE__*/e(\"p\",{children:\"Phew! That\u2019s a lot of text for something that seems obvious, but actually, that\u2019s not all. With ChatGPT it also helps to give it an example, so we will also add this to the prompt:\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"An example exchange is as follows:\\n\\nuser:\\nA wizard enters a dungeon.\\n\\nassistant:\\nStory: An aged wizard quietly enters a dark dungeon. He can tell by the echo of his footsteps that the chamber is large and surprisingly empty.\\nCaption: A grey-bearded wizard with a flowing blue  cloack, a blue hat, and a long grey beard, and a 6-foot wooden staff entering a dark dungeon with high ceilings from the left side of the frame.\\nChoice1: The wizard illuminates the dungeon\\nChoice2: The wizard turns himself invisible\",language:\"Markdown\"})})}),/*#__PURE__*/e(\"h3\",{children:\"Generating our CYOA Content\"}),/*#__PURE__*/t(\"p\",{children:[\"We are going to store the combined text in a variable named \",/*#__PURE__*/e(\"code\",{children:\"system_directive\"}),\" and then we can create a function for our CYOA text. Place the code above \",/*#__PURE__*/e(\"code\",{children:\"@app.route(\u2019/submit\u2019, methods=[\u2019POST\u2019])\"}),\" .\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:'def generate_cyoa(choice):\\n\tmessage_payload = [{\"role\": \"system\", \"content\": system_directive}, {\"role\": \"user\", \"content\": choice}]\\n\t\\n\tchat_response = client.chat.completions.create(\\n\t\t\tmodel=\"gpt-4o\",\\n\t\t\tmessages=messages_payload,\\n\t\t\tfrequency_penalty=1.0, temperature=0.8\\n\t)\\n\t\\n\treturn chat_response.choices[0].message_content',language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"The most important part of this code is the message payload. Essentially, the first section is constraining the system to the format in our long prompt, and the second part is taking the user\u2019s choice and passing it along.\"}),/*#__PURE__*/t(\"p\",{children:[\"We also need to modify our \",/*#__PURE__*/e(\"code\",{children:\"submit()\"}),\" now.\"]}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"@app.route('/submit', methods=['POST'])\\ndef submit():\\n\tchoice = request.form['choice']\\n\tcyoa = generate_cyoa(choice)\\n\treturn f'The AI responded with: {cyoa}'\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"Here we\u2019ve added a variable that takes the return of generate_cyoa() when fed the user\u2019s choice. The return has also been modified to produce a string of the response.\"}),/*#__PURE__*/e(\"p\",{children:\"This is the response we got from our test run. Yours will be different, but should adhere to the same format.\"}),/*#__PURE__*/e(\"img\",{alt:\"\",className:\"framer-image\",height:\"53\",src:\"https://framerusercontent.com/images/ZJY6Tq96trSFCVD5NUD5zyVYozc.png\",srcSet:\"https://framerusercontent.com/images/ZJY6Tq96trSFCVD5NUD5zyVYozc.png?scale-down-to=512 512w,https://framerusercontent.com/images/ZJY6Tq96trSFCVD5NUD5zyVYozc.png?scale-down-to=1024 1024w,https://framerusercontent.com/images/ZJY6Tq96trSFCVD5NUD5zyVYozc.png 1199w\",style:{aspectRatio:\"1199 / 106\"},width:\"599\"}),/*#__PURE__*/e(\"p\",{children:\"Don\u2019t get scared, but we are going to use Regex. Regular expressions used to be scary, but now you can just feed the response above back into ChatGPT and ask it to help you parse it with Regex, and voila.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"import re\\nfrom typing import mapping\\n\\n# Place at the top ^^\\n\\ndef get_caption(chat_response_object: Mapping) -> str:\\n\treturn (\\n\t\tre.search(r'Caption:(.*)(?:\\\\n|$)', chat_response_object.content)\\n\t\t.group(1)\\n\t\t.strip()\\n\t)\\n\\n# Place after index()^^\\n\t\",language:\"Python\"})})}),/*#__PURE__*/e(\"p\",{children:\"This same structure can be applied for each variable we want to parse from the response, including Story, Caption, Choice1, and Choice2.\"}),/*#__PURE__*/e(\"p\",{children:\"Next we will modify our submit function to retrieve all of the parsed outputs and load them into the render_template.\"}),/*#__PURE__*/e(\"div\",{className:\"framer-text-module\",style:{height:\"auto\",width:\"100%\"},children:/*#__PURE__*/e(n,{componentIdentifier:\"module:pVk4QsoHxASnVtUBp6jr/QVzZltTawVJTjmjAWG3C/CodeBlock.js:default\",children:t=>/*#__PURE__*/e(s,{...t,code:\"def submit():\\n\tchoice = request.form['choice']\\n\tcyoa = generate_cyoa(choice)\\n\tcaption_text = get_caption(cyoa)\\n\tstory_text = get_story(cyoa)\\n\tchoice1_text = get_choice1(cyoa)\\n\tchoice2_text = get_choice2(cyoa)\\n\timg_path = generate_image(caption_text)\\n\treturn render_template('index.html', story=story_text, button_name1=choice1_text, button_name2=choice2_text, img_path=img_path)\",language:\"Python\"})})}),/*#__PURE__*/t(\"p\",{children:[\"You\u2019re almost at the finish line. Just launch \",/*#__PURE__*/e(\"code\",{children:\"python app.py\"}),\" in the terminal and you should have a working CYOA game. If you run into any trouble, you can find the \",/*#__PURE__*/e(o,{href:\"https://github.com/godfreynolan/cyoa\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"code here on Github\"})}),\".\"]}),/*#__PURE__*/e(\"h1\",{children:\"Conclusion\"}),/*#__PURE__*/e(\"p\",{children:\"In this tutorial, you learned how to create a classic Choose Your Own Adventure game from scratch using the ChatGPT API and Python. You applied your knowledge of making API calls to OpenAI to get responses from the ChatGPT language model and modified those responses to generate an interactive story experience with branching narrative paths. You used Python to build a simple web application with Flask that renders the story and choices from the API. This provides a great foundation for learning more advanced natural language processing and generative AI applications by integrating large language models like ChatGPT into interactive experiences.\"}),/*#__PURE__*/t(\"h3\",{children:[\"Join the \",/*#__PURE__*/e(o,{href:\"https://www.meetup.com/practical-chatgpt-api-programming/\",motionChild:!0,nodeId:\"ku4Vf4CtH\",openInNewTab:!1,scopeId:\"contentManagement\",smoothScroll:!1,children:/*#__PURE__*/e(a.a,{children:\"OpenAI Application Explorers Meetup Group\"})}),\" to learn more about awesome apps you can build with AI\"]})]});\nexport const __FramerMetadata__ = {\"exports\":{\"richText3\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"richText2\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"richText4\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"richText1\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"richText\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}"],
  "mappings": "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",
  "names": ["richText", "u", "x", "p", "ComponentPresetsConsumer", "Youtube", "CodeBlock_default", "Link", "motion", "richText1", "richText2", "richText3", "richText4", "__FramerMetadata__"]
}
