Skip to content

Commit

Permalink
Merge dev + fix version string issue
Browse files Browse the repository at this point in the history
  • Loading branch information
BrandonPacewic committed Aug 26, 2024
2 parents a3685b4 + 43f9225 commit 706bc60
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ExporterOptions:
exportAsPart: bool = field(default=False)

exportLocation: ExportLocation = field(default=ExportLocation.DOWNLOAD)
openSynthesisUponExport: bool = field(default=False)

hierarchy: ModelHierarchy = field(default=ModelHierarchy.FusionAssembly)
visualQuality: TriangleMeshQualityOptions = field(default=TriangleMeshQualityOptions.LowQualityTriangleMesh)
Expand Down
13 changes: 10 additions & 3 deletions exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"""

import os
import webbrowser
from typing import Any

import adsk.core
import adsk.fusion

from src import gm
from src import APP_WEBSITE_URL, gm
from src.APS.APS import getAuth, getUserInfo
from src.Logging import getLogger, logFailure
from src.Parser.ExporterOptions import ExporterOptions
Expand Down Expand Up @@ -127,10 +128,10 @@ def notify(self, _: adsk.core.CommandEventArgs) -> None:
docName, docVersion = designNameSplit[:2]
else:
docName = designNameSplit[0]
docVersion = ""
docVersion = "v0"

processedFileName = gm.app.activeDocument.name.replace(" ", "_")
defaultFileName = "_".join([docName, docVersion]) + ".mira" if docVersion else f"{docName}.mira"
defaultFileName = f"{'_'.join([docName, docVersion])}.mira"
if generalConfigTab.exportLocation == ExportLocation.DOWNLOAD:
savepath = FileDialogConfig.saveFileDialog(exporterOptions.fileLocation, defaultFileName)
else:
Expand Down Expand Up @@ -161,13 +162,19 @@ def notify(self, _: adsk.core.CommandEventArgs) -> None:
exportAsPart=generalConfigTab.exportAsPart,
frictionOverride=generalConfigTab.overrideFriction,
frictionOverrideCoeff=generalConfigTab.frictionOverrideCoeff,
openSynthesisUponExport=generalConfigTab.openSynthesisUponExport,
)

Parser(exporterOptions).export()
exporterOptions.writeToDesign()
jointConfigTab.reset()
gamepieceConfigTab.reset()

if generalConfigTab.openSynthesisUponExport:
res = webbrowser.open(APP_WEBSITE_URL)
if not res:
gm.ui.messageBox("Failed to open Synthesis in your default browser.")


class CommandExecutePreviewHandler(PersistentEventHandler, adsk.core.CommandEventHandler):
"""Called when an execute command is ready to be previewed."""
Expand Down
15 changes: 15 additions & 0 deletions exporter/SynthesisFusionAddin/src/UI/GeneralConfigTab.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ def __init__(self, args: adsk.core.CommandCreatedEventArgs, exporterOptions: Exp
frictionCoefficient.tooltip = "<i>Friction coefficients range from 0 (ice) to 1 (rubber).</i>"
frictionCoefficient.isVisible = exporterOptions.frictionOverride

createBooleanInput(
"openSynthesisOnExportButton",
"Open Synthesis on Export",
generalTabInputs,
checked=exporterOptions.openSynthesisUponExport,
tooltip="Launch the Synthesis website upon export.",
)

if exporterOptions.exportMode == ExportMode.FIELD:
autoCalcWeightButton.isVisible = False
exportAsPartButton.isVisible = False
Expand Down Expand Up @@ -182,6 +190,13 @@ def frictionOverrideCoeff(self) -> float:
)
return frictionSlider.valueOne or -1.0

@property
def openSynthesisUponExport(self) -> bool:
openSynthesisButton: adsk.core.BoolValueCommandInput = self.generalOptionsTab.children.itemById(
"openSynthesisOnExportButton"
)
return openSynthesisButton.value or False

@logFailure
def handleInputChanged(self, args: adsk.core.InputChangedEventArgs) -> None:
autoCalcWeightButton: adsk.core.BoolValueCommandInput = args.inputs.itemById("autoCalcWeightButton")
Expand Down
1 change: 1 addition & 0 deletions exporter/SynthesisFusionAddin/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

APP_NAME = "Synthesis"
APP_TITLE = "Synthesis Robot Exporter"
APP_WEBSITE_URL = "https://synthesis.autodesk.com/fission/"
DESCRIPTION = "Exports files from Fusion into the Synthesis Format"
INTERNAL_ID = "Synthesis"
ADDIN_PATH = os.path.dirname(os.path.realpath(__file__))
Expand Down
4 changes: 2 additions & 2 deletions fission/src/ui/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const Modal: React.FC<ModalProps> = ({
<div
id={modalId}
key={modalId}
className={`${className} flex flex-col absolute max-w-[98vw] max-h-[90vh] w-fit h-fit left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-background text-main-text m-auto border-5 rounded-2xl shadow-sm shadow-slate-800`}
className={`${className} flex flex-col absolute max-w-[50vw] max-h-[95vh] w-fit h-fit left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-background text-main-text m-auto border-5 rounded-2xl shadow-sm shadow-slate-800`}
>
{name && (
<div id="header" className="flex items-center gap-8 h-16">
Expand All @@ -78,7 +78,7 @@ const Modal: React.FC<ModalProps> = ({
id="content"
className={`${contentClassName || ""} ${
!contentClassName?.includes("mx") ? "mx-[2rem]" : ""
} flex flex-col gap-4 max-h-75vh p-4`}
} flex flex-col gap-4 max-h-[75vh]`}
>
{children}
</div>
Expand Down
4 changes: 2 additions & 2 deletions fission/src/ui/components/StyledComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Label, { LabelSize } from "./Label"
import Button, { ButtonProps, ButtonSize } from "./Button"
import { IoCheckmark, IoPencil, IoPeople, IoTrashBin } from "react-icons/io5"
import { HiDownload } from "react-icons/hi"
import { AiOutlinePlus } from "react-icons/ai"
import { BiRefresh } from "react-icons/bi"
import { AiFillWarning } from "react-icons/ai"
import { BsCodeSquare } from "react-icons/bs"
Expand Down Expand Up @@ -58,7 +57,8 @@ export class SynthesisIcons {
/** Large icons: used for icon buttons */
public static DeleteLarge = (<IoTrashBin size={"1.25rem"} />)
public static DownloadLarge = (<HiDownload size={"1.25rem"} />)
public static AddLarge = (<AiOutlinePlus size={"1.25rem"} />)
public static AddLarge = (<FaPlus size={"1.25rem"} />)
public static GearLarge = (<FaGear size={"1.25rem"} />)
public static RefreshLarge = (<BiRefresh size={"1.25rem"} />)
public static SelectLarge = (<IoCheckmark size={"1.25rem"} />)
public static EditLarge = (<IoPencil size={"1.25rem"} />)
Expand Down
43 changes: 27 additions & 16 deletions fission/src/ui/modals/configuring/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import React, { useState } from "react"
import Modal, { ModalPropsImpl } from "@/components/Modal"
import { FaGear } from "react-icons/fa6"
import Label, { LabelSize } from "@/components/Label"
import Dropdown from "@/components/Dropdown"
import Slider from "@/components/Slider"
import Checkbox from "@/components/Checkbox"
import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
import { SceneOverlayEvent, SceneOverlayEventKey } from "@/ui/components/SceneOverlayEvents"
import { QualitySetting } from "@/systems/preferences/PreferenceTypes"
import { Box } from "@mui/material"
import { Spacer } from "@/ui/components/StyledComponents"
import { Spacer, SynthesisIcons } from "@/ui/components/StyledComponents"
import World from "@/systems/World"

const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
const [qualitySettings, setQualitySettings] = useState<string>(
PreferencesSystem.getGlobalPreference<string>("QualitySettings")
)
const [zoomSensitivity, setZoomSensitivity] = useState<number>(

// Disabled until camera settings are implemented
/* const [zoomSensitivity, setZoomSensitivity] = useState<number>(
PreferencesSystem.getGlobalPreference<number>("ZoomSensitivity")
)
const [pitchSensitivity, setPitchSensitivity] = useState<number>(
PreferencesSystem.getGlobalPreference<number>("PitchSensitivity")
)
const [yawSensitivity, setYawSensitivity] = useState<number>(
PreferencesSystem.getGlobalPreference<number>("YawSensitivity")
)
) */

const [reportAnalytics, setReportAnalytics] = useState<boolean>(
PreferencesSystem.getGlobalPreference<boolean>("ReportAnalytics")
)
const [useMetric, setUseMetric] = useState<boolean>(PreferencesSystem.getGlobalPreference<boolean>("UseMetric"))

// Disabled until use metric is implemented
// const [useMetric, setUseMetric] = useState<boolean>(PreferencesSystem.getGlobalPreference<boolean>("UseMetric"))

const [renderScoringZones, setRenderScoringZones] = useState<boolean>(
PreferencesSystem.getGlobalPreference<boolean>("RenderScoringZones")
)
Expand All @@ -44,29 +48,32 @@ const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {

const saveSettings = () => {
PreferencesSystem.setGlobalPreference<string>("QualitySettings", qualitySettings)
PreferencesSystem.setGlobalPreference<number>("ZoomSensitivity", zoomSensitivity)
PreferencesSystem.setGlobalPreference<number>("PitchSensitivity", pitchSensitivity)
PreferencesSystem.setGlobalPreference<number>("YawSensitivity", yawSensitivity)

PreferencesSystem.setGlobalPreference<boolean>("ReportAnalytics", reportAnalytics)
PreferencesSystem.setGlobalPreference<boolean>("UseMetric", useMetric)
PreferencesSystem.setGlobalPreference<boolean>("RenderScoringZones", renderScoringZones)
PreferencesSystem.setGlobalPreference<boolean>("RenderSceneTags", renderSceneTags)
PreferencesSystem.setGlobalPreference<boolean>("RenderScoreboard", renderScoreboard)
PreferencesSystem.setGlobalPreference<boolean>("SubsystemGravity", subsystemGravity)

// Disabled until these settings are implemented
/* PreferencesSystem.setGlobalPreference<number>("ZoomSensitivity", zoomSensitivity)
PreferencesSystem.setGlobalPreference<number>("PitchSensitivity", pitchSensitivity)
PreferencesSystem.setGlobalPreference<number>("YawSensitivity", yawSensitivity)
PreferencesSystem.setGlobalPreference<boolean>("UseMetric", useMetric) */

PreferencesSystem.savePreferences()
}

return (
<Modal
name="Settings"
icon={<FaGear />}
icon={SynthesisIcons.GearLarge}
modalId={modalId}
onAccept={() => {
saveSettings()
}}
>
<div className="flex overflow-y-auto flex-col gap-2 bg-background-secondary rounded-md p-2 max-h-[60vh]">
<div className="flex overflow-y-auto flex-col gap-2 bg-background-secondary rounded-md p-2 max-h-[60vh] min-w-[20vw]">
<Label size={LabelSize.Medium}>Screen Settings</Label>
<Dropdown
label="Quality Settings"
Expand All @@ -77,7 +84,9 @@ const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
World.SceneRenderer.ChangeLighting(selected)
}}
/>
{Spacer(5)}

{/* Disabled until these settings are implemented */}
{/* {Spacer(5)}
<Label size={LabelSize.Medium}>Camera Settings</Label>
<Slider
min={1}
Expand Down Expand Up @@ -106,7 +115,7 @@ const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
format={{ maximumFractionDigits: 2 }}
onChange={(_, value) => setYawSensitivity(value as number)}
tooltipText="Moving the camera left and right."
/>
/>*/}
{Spacer(20)}
<Label size={LabelSize.Medium}>Preferences</Label>
<Box display="flex" flexDirection={"column"}>
Expand All @@ -118,13 +127,15 @@ const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
}}
tooltipText="Record user data such as what robots are spawned and how they are configured. No personal data will be collected."
/>
<Checkbox
{/* Disabled until this settings is implemented */}
{/* <Checkbox
label="Use Metric"
defaultState={PreferencesSystem.getGlobalPreference<boolean>("UseMetric")}
onClick={checked => {
setUseMetric(checked)
}}
/>
tooltipText="Metric measurements. (ex: meters instead of feet)"
/> */}
<Checkbox
label="Realistic Subsystem Gravity"
defaultState={PreferencesSystem.getGlobalPreference<boolean>("SubsystemGravity")}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const NewInputSchemeModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
return (
<Modal
name="New Input Scheme"
icon={SynthesisIcons.Add}
icon={SynthesisIcons.AddLarge}
modalId={modalId}
onAccept={() => {
const scheme = DefaultInputs.newBlankScheme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ const ChooseInputSchemePanel: React.FC<PanelPropsImpl> = ({ panelId }) => {
sidePadding={8}
acceptEnabled={false}
icon={SynthesisIcons.Gamepad}
cancelEnabled={selectedBrainIndexGlobal != undefined}
cancelName="Close"
>
{/** A scroll view with buttons to select default and custom input schemes */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,19 @@ const ConfigureInputsInterface = () => {
// Fetch current custom schemes
InputSchemeManager.saveSchemes()
InputSchemeManager.resetDefaultSchemes()
const schemes = PreferencesSystem.getGlobalPreference<InputScheme[]>("InputSchemes")

// Find and remove this input scheme
// Find the scheme to remove in preferences
const schemes = PreferencesSystem.getGlobalPreference<InputScheme[]>("InputSchemes")
const index = schemes.indexOf(val.scheme)

// If currently bound to a robot, remove the binding
for (const [key, value] of InputSystem.brainIndexSchemeMap.entries()) {
if (value == schemes[index]) {
InputSystem.brainIndexSchemeMap.delete(key)
}
}

// Find and remove this input scheme from preferences
schemes.splice(index, 1)

// Save to preferences
Expand Down
67 changes: 39 additions & 28 deletions simulation/SyntheSimJava/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ This is the SyntheSim Java utility library. FRC users can add this to their proj

## Current 3rd-Party Support

This is a list of the following 3rd-Party libraries that SyntheSim - Java improves, as well as the level of capability currently offered.
A list of the 3rd-Party libraries SyntheSimJava supports, including the features currently offered.

### REVRobotics
- [ ] CANSparkMax

- [x] CANSparkMax
- [x] Basic motor control
- [x] Basic internal encoder data
- [ ] Motor following
- [ ] Full encoder support
- [x] Motor following
- [x] Full encoder support

### CTRE Phoenix v6

### CTRE Phoenix
- [ ] TalonFX
- [ ] Basic motor control
- [ ] Basic internal encoder data
- [ ] Motor following
- [ ] Full encoder support
- [x] TalonFX
- [x] Basic motor control
- [x] Full configuration support (via a [TalonFXConfigurator](src/main/com/autodesk/synthesis/ctre/TalonFXConfigurator.java) wrapper)
- [x] Basic internal encoder data
- [x] Motor following
- [x] Full encoder support

## Building

Expand All @@ -27,15 +30,18 @@ To build the project, run the `build` task:
<details>
<summary>Example</summary>

Windows:
```sh
$ gradlew.bat build
```
Windows:

```sh
gradlew.bat build
```

MacOS/Linux:

```sh
./gradlew build
```

MacOS/Linux:
```sh
$ ./gradlew build
```
</details>

## Usage
Expand All @@ -49,20 +55,23 @@ To publish the project locally, run the `publishToMavenLocal` task:
<details>
<summary>Example</summary>

Windows:
```sh
$ gradlew.bat publishToMavenLocal
```
Windows:

```sh
gradlew.bat publishToMavenLocal
```

MacOS/Linux:

```sh
./gradlew publishToMavenLocal
```

MacOS/Linux:
```sh
$ ./gradlew publishToMavenLocal
```
</details>

### Adding to project locally

In order to add the project locally, you must include the the `mavenLocal()` repository to your projects:
In order to add the project locally, you must include the `mavenLocal()` repository to your projects:

```groovy
repositories {
Expand All @@ -83,4 +92,6 @@ dependencies {

### Swapping Imports

SyntheSimJava creates alternative classes that wrap the original ones. Everything that we intercept is passed on to the original class, making it so these classes can (although not recommended) be used when running your robot code on original hardware. Be sure to switch over any and all CAN devices that this project supports in order to effectively simulate your code inside of Synthesis, or with any HALSim, WebSocket supported simulation/device.
SyntheSimJava creates alternative classes that wrap the original ones. Everything that we intercept is passed on to the original class, making it so these classes can (although not recommended) be used when running your robot code on original hardware. Be sure to switch over any and all CAN devices that this project supports in order to effectively simulate your code inside of Synthesis, or with any HALSim, WebSocket supported simulation/device.

The one exception to this is the `CANSparkMax.getAbsoluteEncoder()` method, which you must substitute for the `CANSparkMax.getAbsoluteEncoderSim()` method, because we were unable to override the original, because we are unable to wrap the return type `SparkAbsoluteEncoder`, because it's constructor is private. We instead created a class that implements all the same interfaces and has all the same methods, and thus works exactly the same, except it isn't an explicit subclass of `SparkAbsoluteEncoder`. The only difference to the API is the method name, everything else operates identically.
Loading

0 comments on commit 706bc60

Please sign in to comment.