diff --git a/i18n/i18n.json b/i18n/i18n.json new file mode 100644 index 00000000..c8d19cbf --- /dev/null +++ b/i18n/i18n.json @@ -0,0 +1,1069 @@ +{ + "": { + "Robot": { + "en-US": "Robot" + }, + "Base Scene - Surface A": { + "en-US": "Base Scene - Surface A" + }, + "A base scene using Surface A. Intended to be augmented to create full JBC scenes": { + "en-US": "A base scene using Surface A. Intended to be augmented to create full JBC scenes" + }, + "JBC Surface A": { + "en-US": "JBC Surface A" + }, + "Ground": { + "en-US": "Ground" + }, + "Light": { + "en-US": "Light" + }, + "Base Scene - Surface B": { + "en-US": "Base Scene - Surface B" + }, + "A base scene using Surface B. Intended to be augmented to create full JBC scenes": { + "en-US": "A base scene using Surface B. Intended to be augmented to create full JBC scenes" + }, + "JBC Surface B": { + "en-US": "JBC Surface B" + }, + "Can %s": { + "en-US": "Can %s" + }, + "JBC Sandbox A": { + "en-US": "JBC Sandbox A" + }, + "Junior Botball Challenge Sandbox on Mat A. All cans 1-12 are available by default.": { + "en-US": "Junior Botball Challenge Sandbox on Mat A. All cans 1-12 are available by default." + }, + "Paper Ream 1": { + "en-US": "Paper Ream 1" + }, + "Paper Ream 2": { + "en-US": "Paper Ream 2" + }, + "JBC Sandbox B": { + "en-US": "JBC Sandbox B" + }, + "Junior Botball Challenge Sandbox on Mat B.": { + "en-US": "Junior Botball Challenge Sandbox on Mat B." + }, + "JBC 1": { + "en-US": "JBC 1" + }, + "Junior Botball Challenge 1: Tag, You're It!": { + "en-US": "Junior Botball Challenge 1: Tag, You're It!" + }, + "JBC 2": { + "en-US": "JBC 2" + }, + "Junior Botball Challenge 2: Ring Around the Can": { + "en-US": "Junior Botball Challenge 2: Ring Around the Can" + }, + "JBC 2B": { + "en-US": "JBC 2B" + }, + "Junior Botball Challenge 2B: Ring Around the Can, Sr.": { + "en-US": "Junior Botball Challenge 2B: Ring Around the Can, Sr." + }, + "JBC 2C": { + "en-US": "JBC 2C" + }, + "Junior Botball Challenge 2C: Back It Up": { + "en-US": "Junior Botball Challenge 2C: Back It Up" + }, + "JBC 2D": { + "en-US": "JBC 2D" + }, + "Junior Botball Challenge 2D: Ring Around the Can and Back It Up": { + "en-US": "Junior Botball Challenge 2D: Ring Around the Can and Back It Up" + }, + "JBC 3": { + "en-US": "JBC 3" + }, + "Junior Botball Challenge 3: Precision Parking": { + "en-US": "Junior Botball Challenge 3: Precision Parking" + }, + "JBC 3B": { + "en-US": "JBC 3B" + }, + "Junior Botball Challenge 3B: Parallel Parking": { + "en-US": "Junior Botball Challenge 3B: Parallel Parking" + }, + "JBC 3C": { + "en-US": "JBC 3C" + }, + "Junior Botball Challenge 3C: Quick Get Away!": { + "en-US": "Junior Botball Challenge 3C: Quick Get Away!" + }, + "JBC 4": { + "en-US": "JBC 4" + }, + "Junior Botball Challenge 4: Figure Eight": { + "en-US": "Junior Botball Challenge 4: Figure Eight" + }, + "JBC 4B": { + "en-US": "JBC 4B" + }, + "Junior Botball Challenge 4B: Barrel Racing": { + "en-US": "Junior Botball Challenge 4B: Barrel Racing" + }, + "JBC 5": { + "en-US": "JBC 5" + }, + "Junior Botball Challenge 5: Dance Party": { + "en-US": "Junior Botball Challenge 5: Dance Party" + }, + "JBC 5B": { + "en-US": "JBC 5B" + }, + "Junior Botball Challenge 5B: Line Dance": { + "en-US": "Junior Botball Challenge 5B: Line Dance" + }, + "JBC 5C": { + "en-US": "JBC 5C" + }, + "Junior Botball Challenge 5C: Synchronized Dancing": { + "en-US": "Junior Botball Challenge 5C: Synchronized Dancing" + }, + "JBC 6": { + "en-US": "JBC 6" + }, + "Junior Botball Challenge 6: Load 'Em Up": { + "en-US": "Junior Botball Challenge 6: Load 'Em Up" + }, + "JBC 6B": { + "en-US": "JBC 6B" + }, + "Junior Botball Challenge 6B: Pick 'Em Up": { + "en-US": "Junior Botball Challenge 6B: Pick 'Em Up" + }, + "JBC 6C": { + "en-US": "JBC 6C" + }, + "Junior Botball Challenge 6C: Empty the Garage": { + "en-US": "Junior Botball Challenge 6C: Empty the Garage" + }, + "Circle 2": { + "en-US": "Circle 2" + }, + "Circle 9": { + "en-US": "Circle 9" + }, + "Circle 10": { + "en-US": "Circle 10" + }, + "Mat Surface": { + "en-US": "Mat Surface" + }, + "JBC 7": { + "en-US": "JBC 7" + }, + "Junior Botball Challenge 7: Bulldozer Mania": { + "en-US": "Junior Botball Challenge 7: Bulldozer Mania" + }, + "JBC 7B": { + "en-US": "JBC 7B" + }, + "Junior Botball Challenge 7B: Cover Your Bases": { + "en-US": "Junior Botball Challenge 7B: Cover Your Bases" + }, + "JBC 8": { + "en-US": "JBC 8" + }, + "Junior Botball Challenge 8: Serpentine": { + "en-US": "Junior Botball Challenge 8: Serpentine" + }, + "JBC 8B": { + "en-US": "JBC 8B" + }, + "Junior Botball Challenge 8B: Serpentine Jr.": { + "en-US": "Junior Botball Challenge 8B: Serpentine Jr." + }, + "JBC 9": { + "en-US": "JBC 9" + }, + "Junior Botball Challenge 9: Add It Up": { + "en-US": "Junior Botball Challenge 9: Add It Up" + }, + "JBC 9B": { + "en-US": "JBC 9B" + }, + "Junior Botball Challenge 9B: Balancing Act": { + "en-US": "Junior Botball Challenge 9B: Balancing Act" + }, + "JBC 10": { + "en-US": "JBC 10" + }, + "Junior Botball Challenge 10: Solo Joust": { + "en-US": "Junior Botball Challenge 10: Solo Joust" + }, + "JBC 10B": { + "en-US": "JBC 10B" + }, + "Junior Botball Challenge 10: Solo Joust Jr.": { + "en-US": "Junior Botball Challenge 10: Solo Joust Jr." + }, + "JBC 12": { + "en-US": "JBC 12" + }, + "Junior Botball Challenge 12: Unload 'Em": { + "en-US": "Junior Botball Challenge 12: Unload 'Em" + }, + "JBC 13": { + "en-US": "JBC 13" + }, + "Junior Botball Challenge 13: Clean the Mat": { + "en-US": "Junior Botball Challenge 13: Clean the Mat" + }, + "JBC 15B": { + "en-US": "JBC 15B" + }, + "Junior Botball Challenge 15B: Bump Bump": { + "en-US": "Junior Botball Challenge 15B: Bump Bump" + }, + "JBC 17": { + "en-US": "JBC 17" + }, + "Junior Botball Challenge 17: Walk the Line": { + "en-US": "Junior Botball Challenge 17: Walk the Line" + }, + "JBC 17B": { + "en-US": "JBC 17B" + }, + "Junior Botball Challenge 17: Walk the Line II": { + "en-US": "Junior Botball Challenge 17: Walk the Line II" + }, + "JBC 19": { + "en-US": "JBC 19" + }, + "Junior Botball Challenge 19: Mountain Rescue": { + "en-US": "Junior Botball Challenge 19: Mountain Rescue" + }, + "Paper Ream": { + "en-US": "Paper Ream" + }, + "JBC 20": { + "en-US": "JBC 20" + }, + "Junior Botball Challenge 20: Rescue the Cans": { + "en-US": "Junior Botball Challenge 20: Rescue the Cans" + }, + "JBC 21": { + "en-US": "JBC 21" + }, + "Junior Botball Challenge 21: Foot Tall": { + "en-US": "Junior Botball Challenge 21: Foot Tall" + }, + "JBC 22": { + "en-US": "JBC 22" + }, + "Junior Botball Challenge 22: Stackerz": { + "en-US": "Junior Botball Challenge 22: Stackerz" + }, + "Script Playground": { + "en-US": "Script Playground" + }, + "Script tests": { + "en-US": "Script tests" + }, + "Demobot": { + "en-US": "Demobot" + }, + "JBC Challenge 6C": { + "en-US": "JBC Challenge 6C" + }, + "Can A Lifted": { + "en-US": "Can A Lifted" + }, + "Can A picked up": { + "en-US": "Can A picked up" + }, + "Can B Lifted": { + "en-US": "Can B Lifted" + }, + "Can B picked up": { + "en-US": "Can B picked up" + }, + "Can C Lifted": { + "en-US": "Can C Lifted" + }, + "Can C picked up": { + "en-US": "Can C picked up" + }, + "Can A Placed": { + "en-US": "Can A Placed" + }, + "Can A placed on circle 2": { + "en-US": "Can A placed on circle 2" + }, + "Can B Placed": { + "en-US": "Can B Placed" + }, + "Can A placed on circle 9": { + "en-US": "Can A placed on circle 9" + }, + "Can C Placed": { + "en-US": "Can C Placed" + }, + "Can A placed on circle 10": { + "en-US": "Can A placed on circle 10" + }, + "Can A Upright": { + "en-US": "Can A Upright" + }, + "Can A upright on circle 2": { + "en-US": "Can A upright on circle 2" + }, + "Can B Upright": { + "en-US": "Can B Upright" + }, + "Can B upright on circle 9": { + "en-US": "Can B upright on circle 9" + }, + "Can C Upright": { + "en-US": "Can C Upright" + }, + "Can C upright on circle 10": { + "en-US": "Can C upright on circle 10" + }, + "Loading...": { + "en-US": "Loading..." + }, + "Logout": { + "en-US": "Logout" + }, + "Tutorials": { + "en-US": "Tutorials" + }, + "Learn how to get started with the simulator": { + "en-US": "Learn how to get started with the simulator" + }, + "3D Simulator": { + "en-US": "3D Simulator" + }, + "A simulator for the Botball demobot.": { + "en-US": "A simulator for the Botball demobot." + }, + "About": { + "en-US": "About" + }, + "KIPR is a 501(c) 3 organization started to make the long-term educational benefits of robotics accessible to students.": { + "en-US": "KIPR is a 501(c) 3 organization started to make the long-term educational benefits of robotics accessible to students." + }, + "Quick Start": { + "en-US": "Quick Start" + }, + "Navigating in 3D": { + "en-US": "Navigating in 3D" + }, + "Learn the controls for navigating in 3D in the simulator": { + "en-US": "Learn the controls for navigating in 3D in the simulator" + }, + "Robot Section": { + "en-US": "Robot Section" + }, + "How to use the robot section": { + "en-US": "How to use the robot section" + }, + "World Section": { + "en-US": "World Section" + }, + "Learn how to create and manipulate items and scene in the simulator": { + "en-US": "Learn how to create and manipulate items and scene in the simulator" + }, + "Indent": { + "en-US": "Indent" + }, + "Download": { + "en-US": "Download" + }, + "Reset": { + "en-US": "Reset" + }, + "Error(s)": { + "en-US": "Error(s)" + }, + "Warning(s)": { + "en-US": "Warning(s)" + }, + "grams": { + "en-US": "grams" + }, + "kilograms": { + "en-US": "kilograms" + }, + "pounds": { + "en-US": "pounds" + }, + "ounces": { + "en-US": "ounces" + }, + "meters": { + "en-US": "meters" + }, + "centimeters": { + "en-US": "centimeters" + }, + "feet": { + "en-US": "feet" + }, + "inches": { + "en-US": "inches" + }, + "radians": { + "en-US": "radians" + }, + "degrees": { + "en-US": "degrees" + }, + "Can": { + "en-US": "Can" + }, + "Box": { + "en-US": "Box" + }, + "Sphere": { + "en-US": "Sphere" + }, + "Cylinder": { + "en-US": "Cylinder" + }, + "Cone": { + "en-US": "Cone" + }, + "Plane": { + "en-US": "Plane" + }, + "File": { + "en-US": "File" + }, + "Euler": { + "en-US": "Euler" + }, + "Axis Angle": { + "en-US": "Axis Angle" + }, + "Empty": { + "en-US": "Empty" + }, + "Standard Object": { + "en-US": "Standard Object" + }, + "Custom Object": { + "en-US": "Custom Object" + }, + "Point Light": { + "en-US": "Point Light" + }, + "Unset": { + "en-US": "Unset" + }, + "Basic": { + "en-US": "Basic" + }, + "Texture": { + "en-US": "Texture" + }, + "Value": { + "en-US": "Value" + }, + "General": { + "en-US": "General" + }, + "Name": { + "en-US": "Name" + }, + "Type": { + "en-US": "Type" + }, + "Geometry": { + "en-US": "Geometry" + }, + "Item": { + "en-US": "Item" + }, + "Box Options": { + "en-US": "Box Options" + }, + "Size X": { + "en-US": "Size X" + }, + "Size Y": { + "en-US": "Size Y" + }, + "Size Z": { + "en-US": "Size Z" + }, + "Sphere Options": { + "en-US": "Sphere Options" + }, + "Radius": { + "en-US": "Radius" + }, + "Cylinder Options": { + "en-US": "Cylinder Options" + }, + "Height": { + "en-US": "Height" + }, + "Plane Options": { + "en-US": "Plane Options" + }, + "File Options": { + "en-US": "File Options" + }, + "URI": { + "en-US": "URI" + }, + "Material": { + "en-US": "Material" + }, + "Color Type": { + "en-US": "Color Type" + }, + "Color Red": { + "en-US": "Color Red" + }, + "Color Green": { + "en-US": "Color Green" + }, + "Color Blue": { + "en-US": "Color Blue" + }, + "Color Texture URI": { + "en-US": "Color Texture URI" + }, + "Albedo Type": { + "en-US": "Albedo Type" + }, + "Albedo Red": { + "en-US": "Albedo Red" + }, + "Albedo Green": { + "en-US": "Albedo Green" + }, + "Albedo Blue": { + "en-US": "Albedo Blue" + }, + "Albedo Texture URI": { + "en-US": "Albedo Texture URI" + }, + "Reflection Type": { + "en-US": "Reflection Type" + }, + "Reflection Red": { + "en-US": "Reflection Red" + }, + "Reflection Green": { + "en-US": "Reflection Green" + }, + "Reflection Blue": { + "en-US": "Reflection Blue" + }, + "Reflection Texture URI": { + "en-US": "Reflection Texture URI" + }, + "Emissive Type": { + "en-US": "Emissive Type" + }, + "Emissive Red": { + "en-US": "Emissive Red" + }, + "Emissive Green": { + "en-US": "Emissive Green" + }, + "Emissive Blue": { + "en-US": "Emissive Blue" + }, + "Emissive Texture URI": { + "en-US": "Emissive Texture URI" + }, + "Ambient Type": { + "en-US": "Ambient Type" + }, + "Ambient Red": { + "en-US": "Ambient Red" + }, + "Ambient Green": { + "en-US": "Ambient Green" + }, + "Ambient Blue": { + "en-US": "Ambient Blue" + }, + "Ambient Texture URI": { + "en-US": "Ambient Texture URI" + }, + "Metalness Type": { + "en-US": "Metalness Type" + }, + "Metalness": { + "en-US": "Metalness" + }, + "Metalness Texture URI": { + "en-US": "Metalness Texture URI" + }, + "Position": { + "en-US": "Position" + }, + "X": { + "en-US": "X" + }, + "Y": { + "en-US": "Y" + }, + "Z": { + "en-US": "Z" + }, + "Orientation": { + "en-US": "Orientation" + }, + "Order": { + "en-US": "Order" + }, + "Angle": { + "en-US": "Angle" + }, + "Scale": { + "en-US": "Scale" + }, + "Physics": { + "en-US": "Physics" + }, + "Mass": { + "en-US": "Mass" + }, + "Friction": { + "en-US": "Friction" + }, + "Unnamed Object": { + "en-US": "Unnamed Object" + }, + "Add Item": { + "en-US": "Add Item" + }, + "Accept": { + "en-US": "Accept" + }, + "Settings": { + "en-US": "Settings" + }, + "Add Script": { + "en-US": "Add Script" + }, + "Select Scene": { + "en-US": "Select Scene" + }, + "Save Scene": { + "en-US": "Save Scene" + }, + "Copy Scene": { + "en-US": "Copy Scene" + }, + "Item(s) (%d)": { + "en-US": "Item(s) (%d)" + }, + "Script(s) (%d)": { + "en-US": "Script(s) (%d)" + }, + "Layouts": { + "en-US": "Layouts" + }, + "Overlay": { + "en-US": "Overlay" + }, + "Side": { + "en-US": "Side" + }, + "Options": { + "en-US": "Options" + }, + "Show All": { + "en-US": "Show All" + }, + "Hide All": { + "en-US": "Hide All" + }, + "Clear": { + "en-US": "Clear" + }, + "Rotation": { + "en-US": "Rotation" + }, + "Start Location": { + "en-US": "Start Location" + }, + "Motor Velocity Plot": { + "en-US": "Motor Velocity Plot" + }, + "Motor Position Plot": { + "en-US": "Motor Position Plot" + }, + "Analog Sensor Plot": { + "en-US": "Analog Sensor Plot" + }, + "Digital Sensor Plot": { + "en-US": "Digital Sensor Plot" + }, + "Analog Sensors": { + "en-US": "Analog Sensors" + }, + "Digital Sensors": { + "en-US": "Digital Sensors" + }, + "Servos": { + "en-US": "Servos" + }, + "Motor Velocities": { + "en-US": "Motor Velocities" + }, + "Motor Positions": { + "en-US": "Motor Positions" + }, + "This process is taking longer than expected...\nIf you have a poor internet connection, this can take some time": { + "en-US": "This process is taking longer than expected...\nIf you have a poor internet connection, this can take some time" + }, + "The simulator may have failed to load.\nPlease submit a feedback form to let us know!": { + "en-US": "The simulator may have failed to load.\nPlease submit a feedback form to let us know!" + }, + "Initializing Simulator...": { + "en-US": "Initializing Simulator..." + }, + "all of": { + "en-US": "all of" + }, + "one or more of": { + "en-US": "one or more of" + }, + "exactly one of": { + "en-US": "exactly one of" + }, + "once": { + "en-US": "once" + }, + "not": { + "en-US": "not" + }, + "Success": { + "en-US": "Success" + }, + "Failure": { + "en-US": "Failure" + }, + "Editor": { + "en-US": "Editor" + }, + "World": { + "en-US": "World" + }, + "Script Editor": { + "en-US": "Script Editor" + }, + "Console": { + "en-US": "Console" + }, + "Open": { + "en-US": "Open" + }, + "Save": { + "en-US": "Save" + }, + "Save As": { + "en-US": "Save As" + }, + "Delete": { + "en-US": "Delete" + }, + "Documentation": { + "en-US": "Documentation" + }, + "Feedback": { + "en-US": "Feedback" + }, + "Reset World": { + "en-US": "Reset World" + }, + "Layout": { + "en-US": "Layout" + }, + "User Interface": { + "en-US": "User Interface" + }, + "Simulation": { + "en-US": "Simulation" + }, + "Locale": { + "en-US": "Locale" + }, + "Switch languages": { + "en-US": "Switch languages" + }, + "Sensor noise": { + "en-US": "Sensor noise" + }, + "Controls whether sensor outputs are affected by random noise": { + "en-US": "Controls whether sensor outputs are affected by random noise" + }, + "Realistic sensors": { + "en-US": "Realistic sensors" + }, + "Controls whether sensors behave like real-world sensors instead of like ideal sensors. For example, real-world ET sensors are nonlinear": { + "en-US": "Controls whether sensors behave like real-world sensors instead of like ideal sensors. For example, real-world ET sensors are nonlinear" + }, + "Autocomplete": { + "en-US": "Autocomplete" + }, + "Controls autocompletion of code, brackets, and quotes": { + "en-US": "Controls autocompletion of code, brackets, and quotes" + }, + "Version %s (%s)": { + "en-US": "Version %s (%s)" + }, + "Copyright": { + "en-US": "Copyright" + }, + "This software is licensed under the terms of the": { + "en-US": "This software is licensed under the terms of the" + }, + "Thank you to the following contributors and testers:": { + "en-US": "Thank you to the following contributors and testers:" + }, + "Want to help improve the simulator and get your name listed here?": { + "en-US": "Want to help improve the simulator and get your name listed here?" + }, + "GitHub repository": { + "en-US": "GitHub repository" + }, + "We're happy to help you get started!": { + "en-US": "We're happy to help you get started!" + }, + "Give a helpful description of a problem you're facing, or a feature you'd like to request": { + "en-US": "Give a helpful description of a problem you're facing, or a feature you'd like to request" + }, + "Thanks for using the KIPR Simulator! Find a bug? Have a feature request? Let us know!": { + "en-US": "Thanks for using the KIPR Simulator! Find a bug? Have a feature request? Let us know!" + }, + "How has your experience using the KIPR Simulator been?": { + "en-US": "How has your experience using the KIPR Simulator been?" + }, + "Email (optional): ": { + "en-US": "Email (optional): " + }, + "Include anonymous usage data to help KIPR developers": { + "en-US": "Include anonymous usage data to help KIPR developers" + }, + "Please try again,": { + "en-US": "Please try again," + }, + "open an issue on our github page": { + "en-US": "open an issue on our github page" + }, + ", or": { + "en-US": ", or" + }, + "email KIPR.": { + "en-US": "email KIPR." + }, + "Submit": { + "en-US": "Submit" + }, + "Feedback Success": { + "en-US": "Feedback Success" + }, + "Feedback successfully submitted!": { + "en-US": "Feedback successfully submitted!" + }, + "Thank you for helping improve the KIPR Simulator!": { + "en-US": "Thank you for helping improve the KIPR Simulator!" + }, + "Open World": { + "en-US": "Open World" + }, + "Unknown": { + "en-US": "Unknown" + }, + "Description: ": { + "en-US": "Description: " + }, + "Author: ": { + "en-US": "Author: " + }, + "Me": { + "en-US": "Me" + }, + "Select a scene to see more details": { + "en-US": "Select a scene to see more details" + }, + "Description": { + "en-US": "Description" + }, + "New World": { + "en-US": "New World" + }, + "Create": { + "en-US": "Create" + }, + "Delete %s?": { + "en-US": "Delete %s?" + }, + "Are you sure you want to delete %s?": { + "en-US": "Are you sure you want to delete %s?" + }, + "Copy World": { + "en-US": "Copy World" + }, + "Error %d": { + "en-US": "Error %d" + }, + "Closing this dialog will take you back to the last well-known state.": { + "en-US": "Closing this dialog will take you back to the last well-known state." + }, + "If this error persists, please submit feedback.": { + "en-US": "If this error persists, please submit feedback." + }, + "World Settings": { + "en-US": "World Settings" + }, + "CHALLENGE": { + "en-US": "CHALLENGE" + }, + "Start": { + "en-US": "Start" + }, + "Welcome to the KIPR Simulator!\n": { + "en-US": "Welcome to the KIPR Simulator!\n" + }, + "Compiling...\n": { + "en-US": "Compiling...\n" + }, + "Compilation succeeded with warnings.\n": { + "en-US": "Compilation succeeded with warnings.\n" + }, + "Compilation succeeded.\n": { + "en-US": "Compilation succeeded.\n" + }, + "Compilation failed.\n": { + "en-US": "Compilation failed.\n" + }, + "Something went wrong during compilation.\n": { + "en-US": "Something went wrong during compilation.\n" + }, + "Compilation succeeded with warnings\n": { + "en-US": "Compilation succeeded with warnings\n" + }, + "Compilation succeeded\n": { + "en-US": "Compilation succeeded\n" + }, + "Modules": { + "en-US": "Modules" + }, + "Functions": { + "en-US": "Functions" + }, + "Structures": { + "en-US": "Structures" + }, + "Enumerations": { + "en-US": "Enumerations" + }, + "Files": { + "en-US": "Files" + }, + "Search...": { + "en-US": "Search..." + }, + "Detailed Description": { + "en-US": "Detailed Description" + }, + "Parameters": { + "en-US": "Parameters" + }, + "Return Value": { + "en-US": "Return Value" + }, + "Fields": { + "en-US": "Fields" + }, + "Volume": { + "en-US": "Volume" + }, + "RGB": { + "en-US": "RGB" + }, + "Challenge": { + "en-US": "Challenge" + }, + "Stop": { + "en-US": "Stop" + }, + "Run": { + "en-US": "Run" + }, + "and External Contributors": { + "en-US": "and External Contributors" + }, + "Visit our": { + "en-US": "Visit our" + } + }, + "Volume (box) in the 3D scene": { + "Volume": { + "en-US": "Volume" + } + }, + "Red, Green, Blue": { + "RGB": { + "en-US": "RGB" + } + }, + "Computer text command line (e.g., DOS)": { + "Console": { + "en-US": "Console" + } + }, + "A predefined task for the user to complete": { + "Challenge": { + "en-US": "Challenge" + } + }, + "Terminate program execution": { + "Stop": { + "en-US": "Stop" + } + }, + "Begin program execution": { + "Run": { + "en-US": "Run" + } + }, + "Part of copyright notice, after KIPR is listed": { + "and External Contributors": { + "en-US": "and External Contributors" + } + }, + "URL link to github repository follows": { + "Visit our": { + "en-US": "Visit our" + } + }, + "Rotation order": { + "XYZ": { + "en-US": "XYZ" + }, + "YZX": { + "en-US": "YZX" + }, + "ZXY": { + "en-US": "ZXY" + }, + "XZY": { + "en-US": "XZY" + }, + "YXZ": { + "en-US": "YXZ" + }, + "ZYX": { + "en-US": "ZYX" + } + } +} \ No newline at end of file diff --git a/src/SceneBinding.ts b/src/SceneBinding.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/ScriptManager/ScriptSceneBinding.ts b/src/ScriptManager/ScriptSceneBinding.ts new file mode 100644 index 00000000..4500f5a0 --- /dev/null +++ b/src/ScriptManager/ScriptSceneBinding.ts @@ -0,0 +1,49 @@ +import Dict from '../util/objectOps/Dict'; +import Camera from '../state/State/Scene/Camera'; +import Geometry from '../state/State/Scene/Geometry'; +import Node from '../state/State/Scene/Node'; +import { Vector3wUnits } from '../util/math/unitMath'; + +export type Ids = string | string[] | Set; + +export namespace Ids { + export const toSet = (ids: Ids): Set => { + if (typeof ids === 'string') return new Set([ids]); + if (Array.isArray(ids)) return new Set(ids); + return ids; + }; +} + +export interface ScriptSceneBinding { + readonly nodes: Dict; + addNode(node: Node, id?: string): string; + removeNode(id: string): void; + setNode(id: string, node: Node); + + readonly geometry: Dict; + addGeometry(geometry: Geometry, id?: string): string; + removeGeometry(id: string): void; + + gravity: Vector3wUnits; + + camera: Camera; + + selectedNodeId?: string; + + readonly programStatus: 'running' | 'stopped'; + + addOnRenderListener(cb: () => void): string; + addOnCollisionListener(nodeId: string, cb: (otherNodeId: string, point: Vector3wUnits) => void, filterIds: Ids): string; + addOnIntersectionListener(nodeId: string, cb: (type: 'start' | 'end', otherNodeId: string) => void, filterIds: Ids): string; + addOnClickListener(filterIds: Ids, cb: (nodeId: string) => void): string; + removeListener(handle: string): void; + + onBind?: (nodeId: string) => void; + onUnbind?: (nodeId: string) => void; + onDispose?: () => void; + + // Used only for unit tests + postTestResult: (data: unknown) => void; + + setChallengeEventValue: (eventId: string, value: boolean) => void; +} \ No newline at end of file diff --git a/src/components/Challenge/ChallengeMenu.tsx b/src/components/Challenge/ChallengeMenu.tsx index cc6f5388..a00cd2cf 100644 --- a/src/components/Challenge/ChallengeMenu.tsx +++ b/src/components/Challenge/ChallengeMenu.tsx @@ -8,6 +8,12 @@ import { Layout, LayoutPicker } from '../Layout'; import { SimulatorState } from './SimulatorState'; import { GREEN, RED, ThemeProps } from '../constants/theme'; +import KIPR_LOGO_BLACK from '../../../static/assets/KIPR-Logo-Black-Text-Clear-Large.png'; +import KIPR_LOGO_WHITE from '../../../static/assets/KIPR-Logo-White-Text-Clear-Large.png'; +import { faBars, faFlagCheckered, faBook, faClone, faCogs, faCommentDots, faGlobeAmericas, faPlay, faQuestion, faSignOutAlt, faStop, faSync } from '@fortawesome/free-solid-svg-icons'; +import SceneMenu from '../World/SceneMenu'; +import ExtraMenu from './ExtraMenu'; + namespace SubMenu { export enum Type { None, @@ -60,6 +66,7 @@ export interface MenuProps extends StyleProps, ThemeProps { onDashboardClick: () => void; onLogoutClick: () => void; + onEndChallengeClick: () => void; simulatorState: SimulatorState; } @@ -70,12 +77,6 @@ interface MenuState { type Props = MenuProps; type State = MenuState; -import KIPR_LOGO_BLACK from '../../../static/assets/KIPR-Logo-Black-Text-Clear-Large.png'; -import KIPR_LOGO_WHITE from '../../../static/assets/KIPR-Logo-White-Text-Clear-Large.png'; -import { faBars, faBook, faClone, faCogs, faCommentDots, faGlobeAmericas, faPlay, faQuestion, faSignOutAlt, faStop, faSync } from '@fortawesome/free-solid-svg-icons'; -import SceneMenu from '../World/SceneMenu'; -import ExtraMenu from './ExtraMenu'; - const Container = styled('div', (props: ThemeProps) => ({ backgroundColor: props.theme.backgroundColor, color: props.theme.color, @@ -226,6 +227,7 @@ class ChallengeMenu extends React.PureComponent { onDocumentationClick, onDashboardClick, onLogoutClick, + onEndChallengeClick, simulatorState } = props; @@ -263,6 +265,16 @@ class ChallengeMenu extends React.PureComponent { + + End Challenge + + + + + End Challenge + + + Layout {subMenu.type === SubMenu.Type.LayoutPicker ? ( diff --git a/src/components/Challenge/SimMenu.tsx b/src/components/Challenge/SimMenu.tsx index 98cc8bca..aaec3cc9 100644 --- a/src/components/Challenge/SimMenu.tsx +++ b/src/components/Challenge/SimMenu.tsx @@ -101,9 +101,6 @@ interface MenuState { type Props = MenuPublicProps & MenuPrivateProps; type State = MenuState; - - - const Container = styled('div', (props: ThemeProps) => ({ backgroundColor: props.theme.backgroundColor, color: props.theme.color, diff --git a/src/pages/ChallengeRoot.tsx b/src/pages/ChallengeRoot.tsx index 10833d96..670923d1 100644 --- a/src/pages/ChallengeRoot.tsx +++ b/src/pages/ChallengeRoot.tsx @@ -726,6 +726,10 @@ class Root extends React.Component { }); }; + private onEndChallengeClick_ = () => { + window.location.href = `/scene/${this.props.match.params.challengeId}`; + }; + private onResetCode_ = () => { this.setState({ modal: Modal.RESET_CODE @@ -873,6 +877,7 @@ class Root extends React.Component { onDocumentationClick={onDocumentationClick} onDashboardClick={this.onDashboardClick} onLogoutClick={this.onLogoutClick} + onEndChallengeClick={this.onEndChallengeClick_} simulatorState={simulatorState} /> {impl} diff --git a/src/programming/SharedRegistersRobot.ts b/src/programming/SharedRegistersRobot.ts index 90f2c8a3..1fb912a3 100644 --- a/src/programming/SharedRegistersRobot.ts +++ b/src/programming/SharedRegistersRobot.ts @@ -6,7 +6,7 @@ import { clamp } from '../util/math/math'; import RegisterState from './registers/RegisterState'; import SharedRegisters from './registers/SharedRegisters'; -class SharedRegistersRobot implements AbstractRobot { +export class SharedRegistersRobot implements AbstractRobot { private sharedResisters_: SharedRegisters; private static readonly POSITION_GOAL_SCALING = 250; diff --git a/src/simulator/ScriptManager.ts b/src/simulator/ScriptManager.ts index a994f84b..95ec08f5 100644 --- a/src/simulator/ScriptManager.ts +++ b/src/simulator/ScriptManager.ts @@ -10,6 +10,7 @@ import { v4 as uuid } from 'uuid'; import construct from '../util/redux/construct'; import { RawAxisAngle, RawQuaternion, RawReferenceFrame, RawVector3 } from '../util/math/math'; import { Angle, Mass, Distance } from '../util/math/Value'; +import { SharedRegistersRobot } from '../programming/SharedRegistersRobot'; export type Ids = string | string[] | Set; @@ -57,7 +58,6 @@ export interface ScriptSceneBinding { setChallengeEventValue: (eventId: string, value: boolean) => void; } - class ScriptManager { private scene_: Scene; @@ -76,7 +76,7 @@ class ScriptManager { onSelectedNodeIdChange?: (id: string) => void; onChallengeSetEventValue?: (eventId: string, value: boolean) => void; - + onChallengeGetEventValue?: (eventId: string, value: boolean) => boolean; private programStatus_: 'running' | 'stopped' = 'stopped'; get programStatus() { return this.programStatus_; } set programStatus(status: 'running' | 'stopped') { @@ -584,8 +584,19 @@ namespace ScriptManager { setChallengeEventValue(eventId: string, value: boolean) { if (!this.manager_.onChallengeSetEventValue) return; this.manager_.onChallengeSetEventValue(eventId, value); + this.getChallengeEventValue(eventId,value); + } + + getChallengeEventValue(eventId: string, value: boolean) { + if (!this.manager_.onChallengeGetEventValue) return; + return value; + this.getChallengeEventValue(eventId,value); } } + + + + } export default ScriptManager; \ No newline at end of file diff --git a/src/simulator/definitions/challenges/jbc1.ts b/src/simulator/definitions/challenges/jbc1.ts new file mode 100644 index 00000000..4a77553a --- /dev/null +++ b/src/simulator/definitions/challenges/jbc1.ts @@ -0,0 +1,105 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 1' }, + description: { [LocalizedString.EN_US]: `Junior Botball Challenge 1: Tag, You're it!` }, + author: { + type: Author.Type.Organization, + id: 'kipr' + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + can9Touched: { + name: { [LocalizedString.EN_US]: 'Can A Touched' }, + description: { [LocalizedString.EN_US]: 'Can A touched' }, + }, + canAIntersects: { + name: { [LocalizedString.EN_US]: 'Can A Intersects' }, + description: { [LocalizedString.EN_US]: 'Can A intersects circle 9' }, + }, + + canAUpright: { + name: { [LocalizedString.EN_US]: 'Can A Upright' }, + description: { [LocalizedString.EN_US]: 'Can A upright on circle 9' }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Rentered Start' }, + description: { [LocalizedString.EN_US]: 'Robot reentered starting box' }, + }, + }, + success: { + exprs: { + // Touch Events + can9Touched: { + type: Expr.Type.Event, + eventId: 'can9Touched', + }, + + // Intersects Events + canAIntersects: { + type: Expr.Type.Event, + eventId: 'canAIntersects', + }, + + // Upright Events + canAUpright: { + type: Expr.Type.Event, + eventId: 'canAUpright', + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + + returnStartBox: { + type: Expr.Type.Event, + eventId: 'returnStartBox', + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: 'returnStartBox', + }, + + + + startingBox:{ + type:Expr.Type.And, + argIds:['leaveStartBoxOnce', 'returnStartBoxOnce'], + }, + + // Intersects and upright logic + aIntersectsUpright: { + type: Expr.Type.And, + argIds: ['canAIntersects', 'canAUpright'], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: ['can9Touched', 'aIntersectsUpright', 'startingBox'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc1', +} as Challenge; \ No newline at end of file diff --git a/src/simulator/definitions/challenges/jbc10.ts b/src/simulator/definitions/challenges/jbc10.ts new file mode 100644 index 00000000..48c4e2ed --- /dev/null +++ b/src/simulator/definitions/challenges/jbc10.ts @@ -0,0 +1,89 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 10' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 10: Solo Joust`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + + can1Upright: { + name: { [LocalizedString.EN_US]: 'Can A Upright' }, + description: { + [LocalizedString.EN_US]: 'Can A upright in a circle', + }, + }, + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + robotTouchingLine: { + name: { [LocalizedString.EN_US]: 'Robot Touching Line B' }, + description: { [LocalizedString.EN_US]: 'Robot is touching line B' }, + }, + + }, + success: { + exprs: { + + + // Upright Events + can1Upright: { + type: Expr.Type.Event, + eventId: 'can1Upright', + }, + can1NotUpright: { + type: Expr.Type.Not, + argId: 'can1Upright', + }, + + // Line B Event + robotTouchingLine: { + type: Expr.Type.Event, + eventId: 'robotTouchingLine', + }, + robotNotTouchingLine: { + type: Expr.Type.Not, + argId: 'robotTouchingLine', + }, + + // Can 1 Not Upright and Robot Not Touching Line B + NotUprightNotTouching: { + type: Expr.Type.And, + argIds: ['can1NotUpright', 'robotNotTouchingLine'], + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + + + completion: { + type: Expr.Type.And, + argIds: ['leaveStartBoxOnce', 'NotUprightNotTouching'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc10', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc10b.ts b/src/simulator/definitions/challenges/jbc10b.ts new file mode 100644 index 00000000..1c048cc2 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc10b.ts @@ -0,0 +1,89 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 10B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 10B: Solo Joust Jr.`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + + can1Upright: { + name: { [LocalizedString.EN_US]: 'Can A Upright' }, + description: { + [LocalizedString.EN_US]: 'Can A upright in a circle', + }, + }, + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + robotTouchingLine: { + name: { [LocalizedString.EN_US]: 'Robot Touching Line B' }, + description: { [LocalizedString.EN_US]: 'Robot is touching line B' }, + }, + + }, + success: { + exprs: { + + + // Upright Events + can1Upright: { + type: Expr.Type.Event, + eventId: 'can1Upright', + }, + can1NotUpright: { + type: Expr.Type.Not, + argId: 'can1Upright', + }, + + // Line B Event + robotTouchingLine: { + type: Expr.Type.Event, + eventId: 'robotTouchingLine', + }, + robotNotTouchingLine: { + type: Expr.Type.Not, + argId: 'robotTouchingLine', + }, + + // Can 1 Not Upright and Robot Not Touching Line B + NotUprightNotTouching: { + type: Expr.Type.And, + argIds: ['can1NotUpright', 'robotNotTouchingLine'], + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + + + completion: { + type: Expr.Type.And, + argIds: ['leaveStartBoxOnce', 'NotUprightNotTouching'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc10b', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc12.ts b/src/simulator/definitions/challenges/jbc12.ts new file mode 100644 index 00000000..5cb0f4ab --- /dev/null +++ b/src/simulator/definitions/challenges/jbc12.ts @@ -0,0 +1,98 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 12" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 12: Unload 'Em`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can2Upright: { + name: { [LocalizedString.EN_US]: "Can 2 Upright" }, + description: { [LocalizedString.EN_US]: "Can 2 upright" }, + }, + can9Upright: { + name: { [LocalizedString.EN_US]: "Can 9 Upright" }, + description: { [LocalizedString.EN_US]: "Can 9 upright" }, + }, + can10Upright: { + name: { [LocalizedString.EN_US]: "Can 10 Upright" }, + description: { [LocalizedString.EN_US]: "Can 10 upright" }, + }, + + can2Intersects: { + name: { [LocalizedString.EN_US]: "Can 2 Intersects" }, + description: { [LocalizedString.EN_US]: "Can from green garage intersects circle 2" }, + }, + can9Intersects: { + name: { [LocalizedString.EN_US]: "Can 9 Intersects" }, + description: { [LocalizedString.EN_US]: "Can from blue garage intersects circle 9" }, + }, + can10Intersects: { + name: { [LocalizedString.EN_US]: "Can 10 Intersects" }, + description: { [LocalizedString.EN_US]: "Can from yellow garage intersects circle 10" }, + }, + }, + success: { + exprs: { + // Upright Events + can2Upright: { + type: Expr.Type.Event, + eventId: "can2Upright", + }, + can9Upright: { + type: Expr.Type.Event, + eventId: "can9Upright", + }, + can10Upright: { + type: Expr.Type.Event, + eventId: "can10Upright", + }, + cansUpright: { + type: Expr.Type.And, + argIds: ["can2Upright", "can9Upright", "can10Upright"], + }, + + + // Intersects Events + can2Intersects: { + type: Expr.Type.Event, + eventId: "can2Intersects", + }, + can9Intersects: { + type: Expr.Type.Event, + eventId: "can9Intersects", + }, + can10Intersects: { + type: Expr.Type.Event, + eventId: "can10Intersects", + }, + cansIntersects: { + type: Expr.Type.And, + argIds: ["can2Intersects", "can9Intersects", "can10Intersects"], + }, + + + // Success logic + completion: { + type: Expr.Type.And, + argIds: ["cansUpright", "cansIntersects"], + }, + }, + rootId: "completion", + }, + sceneId: "jbc12", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc13.ts b/src/simulator/definitions/challenges/jbc13.ts new file mode 100644 index 00000000..7f36e8f3 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc13.ts @@ -0,0 +1,139 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 13' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 13: Clean the Mat`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + can2Intersects: { + name: { [LocalizedString.EN_US]: 'Can 2 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 2 intersects chosen garage' }, + }, + can5Intersects: { + name: { [LocalizedString.EN_US]: 'Can 5 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 5 intersects chosen garage' }, + }, + can8Intersects: { + name: { [LocalizedString.EN_US]: 'Can 8 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 8 intersects chosen garage' }, + }, + can10Intersects: { + name: { [LocalizedString.EN_US]: 'Can 10 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 10 intersects chosen garage' }, + }, + can11Intersects: { + name: { [LocalizedString.EN_US]: 'Can 11 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 11 intersects chosen garage' }, + }, + + can2Upright: { + name: { [LocalizedString.EN_US]: 'Can 2 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 2 upright in chosen garage' }, + }, + can5Upright: { + name: { [LocalizedString.EN_US]: 'Can 5 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 5 upright in achosen garage' }, + }, + can8Upright: { + name: { [LocalizedString.EN_US]: 'Can 8 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 8 upright in chosen garage' }, + }, + can10Upright: { + name: { [LocalizedString.EN_US]: 'Can 10 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 10 upright in chosen garage' }, + }, + can11Upright: { + name: { [LocalizedString.EN_US]: 'Can 11 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 11 upright in chosen garage' }, + }, + + + }, + success: { + exprs: { + + // Intersects Events + can2Intersects: { + type: Expr.Type.Event, + eventId: 'can2Intersects', + }, + can5Intersects: { + type: Expr.Type.Event, + eventId: 'can5Intersects', + }, + can8Intersects: { + type: Expr.Type.Event, + eventId: 'can8Intersects', + }, + can10Intersects: { + type: Expr.Type.Event, + eventId: 'can10Intersects', + }, + can11Intersects: { + type: Expr.Type.Event, + eventId: 'can11Intersects', + }, + + cansIntersects: { + type: Expr.Type.And, + argIds: ['can2Intersects', 'can5Intersects', 'can8Intersects','can10Intersects', 'can11Intersects'], + }, + + // Upright Events + can2Upright: { + type: Expr.Type.Event, + eventId: 'can2Upright', + }, + can5Upright: { + type: Expr.Type.Event, + eventId: 'can5Upright', + }, + can8Upright: { + type: Expr.Type.Event, + eventId: 'can8Upright', + }, + can10Upright: { + type: Expr.Type.Event, + eventId: 'can10Upright', + }, + can11Upright: { + type: Expr.Type.Event, + eventId: 'can11Upright', + }, + + cansUpright: { + type: Expr.Type.And, + argIds: ['can2Upright', 'can5Upright','can8Upright','can10Upright', 'can11Upright'], + }, + + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + + 'cansIntersects', + 'cansUpright' + + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc13', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc15b.ts b/src/simulator/definitions/challenges/jbc15b.ts new file mode 100644 index 00000000..53ddb22c --- /dev/null +++ b/src/simulator/definitions/challenges/jbc15b.ts @@ -0,0 +1,85 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 15B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 15B: Bump Bump`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + driveForwardTouch: { + name: { [LocalizedString.EN_US]: 'Robot Forward Touch' }, + description: { + [LocalizedString.EN_US]: + 'Robot drove forward and touched ream of paper', + }, + }, + + driveBackwardTouch: { + name: { [LocalizedString.EN_US]: 'Robot Backward Touch' }, + description: { + [LocalizedString.EN_US]: + 'Robot drove backward and touched ream of paper', + }, + }, + driveForward2: { + name: { [LocalizedString.EN_US]: 'Robot Forward Circle 2' }, + description: { + [LocalizedString.EN_US]: 'Robot drove forward to circle 2', + }, + }, + }, + success: { + exprs: { + // Ream Touching Events + driveForwardTouch: { + type: Expr.Type.Event, + eventId: 'driveForwardTouch', + }, + driveForwardTouchOnce: { + type: Expr.Type.Once, + argId: 'driveForwardTouch', + }, + driveBackwardTouch: { + type: Expr.Type.Event, + eventId: 'driveBackwardTouch', + }, + driveBackwardTouchOnce: { + type: Expr.Type.Once, + argId: 'driveBackwardTouch', + }, + driveForward2: { + type: Expr.Type.Event, + eventId: 'driveForward2', + }, + driveForward2Once: { + type: Expr.Type.Once, + argId: 'driveForward2', + }, + + completion: { + type: Expr.Type.And, + argIds: [ + 'driveForwardTouchOnce', + 'driveBackwardTouchOnce', + 'driveForward2Once', + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc15b', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc17.ts b/src/simulator/definitions/challenges/jbc17.ts new file mode 100644 index 00000000..648c2220 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc17.ts @@ -0,0 +1,50 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 17' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 17: Walk the Line`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + lineFollow: { + name: { [LocalizedString.EN_US]: 'Robot Walks the Line' }, + description: { + [LocalizedString.EN_US]: + 'Robot uses reflectance sensor to follow the black line until Finish Line ', + }, + }, + }, + success: { + exprs: { + // Line Following Event + lineFollow: { + type: Expr.Type.Event, + eventId: 'lineFollow', + }, + + + completion: { + type: Expr.Type.And, + argIds: [ + 'lineFollow', + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc17', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc17b.ts b/src/simulator/definitions/challenges/jbc17b.ts new file mode 100644 index 00000000..9b67f049 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc17b.ts @@ -0,0 +1,50 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 17B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 17B: Walk the Line II`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + lineFollow: { + name: { [LocalizedString.EN_US]: 'Robot Walks the Line' }, + description: { + [LocalizedString.EN_US]: + 'Robot uses reflectance sensor to follow the black line until the Blue line', + }, + }, + }, + success: { + exprs: { + // Line Following Event + lineFollow: { + type: Expr.Type.Event, + eventId: 'lineFollow', + }, + + + completion: { + type: Expr.Type.And, + argIds: [ + 'lineFollow', + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc17b', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc19.ts b/src/simulator/definitions/challenges/jbc19.ts new file mode 100644 index 00000000..5f203b61 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc19.ts @@ -0,0 +1,137 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 19' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 19: Mountain Rescue`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + can1Upright: { + name: { [LocalizedString.EN_US]: 'Can 1 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 1 is upright', + }, + }, + can2Upright: { + name: { [LocalizedString.EN_US]: 'Can 2 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 2 is upright', + }, + }, + can3Upright: { + name: { [LocalizedString.EN_US]: 'Can 3 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 3 is upright', + }, + }, + can1Intersects: { + name: { [LocalizedString.EN_US]: 'Can 1 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 1 rescued intersecting starting box', + }, + }, + can2Intersects: { + name: { [LocalizedString.EN_US]: 'Can 2 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 2 rescued intersecting starting box', + }, + }, + can3Intersects: { + name: { [LocalizedString.EN_US]: 'Can 3 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 3 rescued intersecting starting box', + }, + }, + }, + success: { + exprs: { + // Rescued upright can events + can1Upright: { + type: Expr.Type.Event, + eventId: 'can1Upright', + }, + can1UprightOnce: { + type: Expr.Type.Once, + argId: 'can1Upright', + }, + can2Upright: { + type: Expr.Type.Event, + eventId: 'can2Upright', + }, + can2UprightOnce: { + type: Expr.Type.Once, + argId: 'can2Upright', + }, + can3Upright: { + type: Expr.Type.Event, + eventId: 'can3Upright', + }, + can3UprightOnce: { + type: Expr.Type.Once, + argId: 'can3Upright', + }, + + // Rescued intersecting can events + can1Intersects: { + type: Expr.Type.Event, + eventId: 'can1Intersects', + }, + can1IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can1Intersects', + }, + can2Intersects: { + type: Expr.Type.Event, + eventId: 'can2Intersects', + }, + can2IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can2Intersects', + }, + can3Intersects: { + type: Expr.Type.Event, + eventId: 'can3Intersects', + }, + can3IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can3Intersects', + }, + + // Intersecting and Upright + IntersectingUpright1: { + type: Expr.Type.And, + argIds: ['can1UprightOnce','can1IntersectsOnce'], + }, + IntersectingUpright2: { + type: Expr.Type.And, + argIds: ['can2UprightOnce','can2IntersectsOnce'], + }, + IntersectingUpright3: { + type: Expr.Type.And, + argIds: ['can3UprightOnce','can3IntersectsOnce'], + }, + + + completion: { + type: Expr.Type.And, + argIds: ['IntersectingUpright1','IntersectingUpright2','IntersectingUpright3'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc19', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc2.ts b/src/simulator/definitions/challenges/jbc2.ts new file mode 100644 index 00000000..f52cd3c5 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc2.ts @@ -0,0 +1,162 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 2" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 2: Ring Around the Can`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can6Touched: { + name: { [LocalizedString.EN_US]: "Can 6 Touched" }, + description: { [LocalizedString.EN_US]: "Can 6 touched" }, + }, + can6Intersects: { + name: { [LocalizedString.EN_US]: "Can 6 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 6 intersects circle 6" }, + }, + + can6Upright: { + name: { [LocalizedString.EN_US]: "Can 6 Upright" }, + description: { [LocalizedString.EN_US]: "Can 6 upright on circle 6" }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + + rightSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Right Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed right side of can 6", + }, + }, + + topSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Top Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed top side of can 6", + }, + }, + + leftSide: { + name: { [LocalizedString.EN_US]: "Robot Passed left Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed left side of can 6", + }, + }, + }, + success: { + exprs: { + // Touch Events + can6Touched: { + type: Expr.Type.Event, + eventId: "can6Touched", + }, + can6NotTouched: { + type: Expr.Type.Not, + argId: "can6Touched", + }, + + // Passing side events + rightSide: { + type: Expr.Type.Event, + eventId: "rightSide", + }, + rightSideOnce: { + type: Expr.Type.Once, + argId: "rightSide", + }, + topSide: { + type: Expr.Type.Event, + eventId: "topSide", + }, + topSideOnce: { + type: Expr.Type.Once, + argId: "topSide", + }, + leftSide: { + type: Expr.Type.Event, + eventId: "leftSide", + }, + leftSideOnce: { + type: Expr.Type.Once, + argId: "leftSide", + }, + + // Intersects Events + can6Intersects: { + type: Expr.Type.Event, + eventId: "can6Intersects", + }, + + // Upright Events + can6Upright: { + type: Expr.Type.Event, + eventId: "can6Upright", + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUpright: { + type: Expr.Type.And, + argIds: ["can6Intersects", "can6Upright"], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + "can6NotTouched", + "IntersectsUpright", + "startingBox", + "rightSideOnce", + "topSideOnce", + "leftSideOnce" + ], + }, + }, + rootId: "completion", + }, + sceneId: "jbc2", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc20.ts b/src/simulator/definitions/challenges/jbc20.ts new file mode 100644 index 00000000..ee1f82ff --- /dev/null +++ b/src/simulator/definitions/challenges/jbc20.ts @@ -0,0 +1,178 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 20' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 20: Rescue the Cans`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + + can2Upright: { + name: { [LocalizedString.EN_US]: 'Can 2 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 2 is upright', + }, + }, + can9Upright: { + name: { [LocalizedString.EN_US]: 'Can 9 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 9 is upright', + }, + }, + can10Upright: { + name: { [LocalizedString.EN_US]: 'Can 10 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 10 is upright', + }, + }, + can12Upright: { + name: { [LocalizedString.EN_US]: 'Can 12 Upright' }, + description: { + [LocalizedString.EN_US]: 'Can 12 is upright', + }, + }, + + can9Intersects: { + name: { [LocalizedString.EN_US]: 'Can 9 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 9 rescued intersecting paper ream', + }, + }, + can2Intersects: { + name: { [LocalizedString.EN_US]: 'Can 2 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 2 rescued intersecting paper ream', + }, + }, + can10Intersects: { + name: { [LocalizedString.EN_US]: 'Can 10 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 10 rescued intersecting paper ream', + }, + }, + can12Intersects: { + name: { [LocalizedString.EN_US]: 'Can 12 Intersects' }, + description: { + [LocalizedString.EN_US]: 'Can 12 rescued intersecting paper ream', + }, + }, + }, + success: { + exprs: { + // Rescued upright can events + can9Upright: { + type: Expr.Type.Event, + eventId: 'can9Upright', + }, + can9UprightOnce: { + type: Expr.Type.Once, + argId: 'can9Upright', + }, + can2Upright: { + type: Expr.Type.Event, + eventId: 'can2Upright', + }, + can2UprightOnce: { + type: Expr.Type.Once, + argId: 'can2Upright', + }, + can10Upright: { + type: Expr.Type.Event, + eventId: 'can10Upright', + }, + can10UprightOnce: { + type: Expr.Type.Once, + argId: 'can10Upright', + }, + can12Upright: { + type: Expr.Type.Event, + eventId: 'can12Upright', + }, + can12UprightOnce: { + type: Expr.Type.Once, + argId: 'can12Upright', + }, + + + // Rescued intersecting can events + can9Intersects: { + type: Expr.Type.Event, + eventId: 'can9Intersects', + }, + can9IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can9Intersects', + }, + can2Intersects: { + type: Expr.Type.Event, + eventId: 'can2Intersects', + }, + can2IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can2Intersects', + }, + can10Intersects: { + type: Expr.Type.Event, + eventId: 'can10Intersects', + }, + can10IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can10Intersects', + }, + can12Intersects: { + type: Expr.Type.Event, + eventId: 'can12Intersects', + }, + can12IntersectsOnce: { + type: Expr.Type.Once, + argId: 'can12Intersects', + }, + + + // Intersecting and Upright + IntersectingUpright9: { + type: Expr.Type.And, + argIds: ['can9Upright', 'can9Intersects'], + }, + IntersectingUpright2: { + type: Expr.Type.And, + argIds: ['can2Upright', 'can2Intersects'], + }, + IntersectingUpright10: { + type: Expr.Type.And, + argIds: ['can10Upright', 'can10Intersects'], + }, + IntersectingUpright12: { + type: Expr.Type.And, + argIds: ['can12Upright', 'can12Intersects'], + }, + + + completion: { + type: Expr.Type.And, + argIds: [ + 'IntersectingUpright9', + 'IntersectingUpright2', + 'IntersectingUpright10', + 'IntersectingUpright12' + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc20', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc21.ts b/src/simulator/definitions/challenges/jbc21.ts new file mode 100644 index 00000000..49e1c1d4 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc21.ts @@ -0,0 +1,45 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 21' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 21: Foot Tall`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + footTallMark: { + name: { [LocalizedString.EN_US]: 'Can 9 Lifted' }, + description: { + [LocalizedString.EN_US]: 'Can 9 Lifted a Foot Tall', + }, + }, + }, + success: { + exprs: { + footTallMark: { + type: Expr.Type.Event, + eventId: 'footTallMark', + }, + + completion: { + type: Expr.Type.And, + argIds: ['footTallMark'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc21', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc22.ts b/src/simulator/definitions/challenges/jbc22.ts new file mode 100644 index 00000000..09230b55 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc22.ts @@ -0,0 +1,78 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 22' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 22: Stackerz`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + + + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + + canStacked: { + name: { [LocalizedString.EN_US]: 'One Can Stacked' }, + description: { [LocalizedString.EN_US]: 'One can is stacked on another' }, + }, + + robotTouchCan: { + name: { [LocalizedString.EN_US]: 'Robot Touching Can' }, + description: { [LocalizedString.EN_US]: 'Robot is touching a can' }, + }, + + }, + success: { + exprs: { + + + // Startbox Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + + // Can Events + canStacked: { + type: Expr.Type.Event, + eventId: 'canStacked', + }, + robotTouchCan: { + type: Expr.Type.Event, + eventId: 'robotTouchCan', + }, + robotTouchCanNot: { + type: Expr.Type.Not, + argId: 'robotTouchCan', + }, + + + completion: { + type: Expr.Type.And, + argIds: ['leaveStartBoxOnce', 'canStacked', 'robotTouchCanNot'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc22', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc2b.ts b/src/simulator/definitions/challenges/jbc2b.ts new file mode 100644 index 00000000..b1f2b323 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc2b.ts @@ -0,0 +1,230 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 2B" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 2B: Ring Around the Cans, Sr.`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can10Touched: { + name: { [LocalizedString.EN_US]: "Can 10 Touched" }, + description: { [LocalizedString.EN_US]: "Can 10 touched" }, + }, + can11Touched: { + name: { [LocalizedString.EN_US]: "Can 11 Touched" }, + description: { [LocalizedString.EN_US]: "Can 11 touched" }, + }, + can12Touched: { + name: { [LocalizedString.EN_US]: "Can 12 Touched" }, + description: { [LocalizedString.EN_US]: "Can 12 touched" }, + }, + + can10Intersects: { + name: { [LocalizedString.EN_US]: "Can 10 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 10 intersects circle 10" }, + }, + can11Intersects: { + name: { [LocalizedString.EN_US]: "Can 11 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 11 intersects circle 11" }, + }, + can12Intersects: { + name: { [LocalizedString.EN_US]: "Can 12 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 12 intersects circle 12" }, + }, + + can10Upright: { + name: { [LocalizedString.EN_US]: "Can 10 Upright" }, + description: { [LocalizedString.EN_US]: "Can 10 upright on circle 10" }, + }, + can11Upright: { + name: { [LocalizedString.EN_US]: "Can 11 Upright" }, + description: { [LocalizedString.EN_US]: "Can 11 upright on circle 11" }, + }, + can12Upright: { + name: { [LocalizedString.EN_US]: "Can 12 Upright" }, + description: { [LocalizedString.EN_US]: "Can 12 upright on circle 12" }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + + rightSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Right Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed right side of can 12", + }, + }, + + topSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Top Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed top side of can 11", + }, + }, + + leftSide: { + name: { [LocalizedString.EN_US]: "Robot Passed left Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed left side of can 10", + }, + }, + }, + success: { + exprs: { + // Touch Events + can10Touched: { + type: Expr.Type.Event, + eventId: "can10Touched", + }, + can10NotTouched: { + type: Expr.Type.Not, + argId: "can10Touched", + }, + can11Touched: { + type: Expr.Type.Event, + eventId: "can11Touched", + }, + can11NotTouched: { + type: Expr.Type.Not, + argId: "can11Touched", + }, + can12Touched: { + type: Expr.Type.Event, + eventId: "can12Touched", + }, + can12NotTouched: { + type: Expr.Type.Not, + argId: "can12Touched", + }, + cansNotTouched: { + type: Expr.Type.And, + argIds: ["can10NotTouched", "can11NotTouched", "can12NotTouched"], + }, + + // Passing side events + rightSide: { + type: Expr.Type.Event, + eventId: "rightSide", + }, + rightSideOnce: { + type: Expr.Type.Once, + argId: "rightSide", + }, + topSide: { + type: Expr.Type.Event, + eventId: "topSide", + }, + topSideOnce: { + type: Expr.Type.Once, + argId: "topSide", + }, + leftSide: { + type: Expr.Type.Event, + eventId: "leftSide", + }, + leftSideOnce: { + type: Expr.Type.Once, + argId: "leftSide", + }, + + // Intersects Events + can10Intersects: { + type: Expr.Type.Event, + eventId: "can10Intersects", + }, + can11Intersects: { + type: Expr.Type.Event, + eventId: "can11Intersects", + }, + can12Intersects: { + type: Expr.Type.Event, + eventId: "can12Intersects", + }, + cansIntersects: { + type: Expr.Type.And, + argIds: ["can10Intersects", "can11Intersects", "can12Intersects"], + }, + + // Upright Events + can10Upright: { + type: Expr.Type.Event, + eventId: "can10Upright", + }, + can11Upright: { + type: Expr.Type.Event, + eventId: "can11Upright", + }, + can12Upright: { + type: Expr.Type.Event, + eventId: "can12Upright", + }, + cansUpright: { + type: Expr.Type.And, + argIds: ["can10Upright", "can11Upright", "can12Upright"], + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUpright: { + type: Expr.Type.And, + argIds: ["cansIntersects", "cansUpright"], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + "cansNotTouched", + "IntersectsUpright", + "startingBox", + "rightSideOnce", + "topSideOnce", + "leftSideOnce", + ], + }, + }, + rootId: "completion", + }, + sceneId: "jbc2b", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc2c.ts b/src/simulator/definitions/challenges/jbc2c.ts new file mode 100644 index 00000000..0ff8427d --- /dev/null +++ b/src/simulator/definitions/challenges/jbc2c.ts @@ -0,0 +1,158 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 2C" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 2C: Back It Up`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can6Intersects: { + name: { [LocalizedString.EN_US]: "Can 6 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 6 intersects circle 6" }, + }, + + can6Upright: { + name: { [LocalizedString.EN_US]: "Can 6 Upright" }, + description: { [LocalizedString.EN_US]: "Can 6 upright on circle 6" }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + + driveBackwards: { + name: { [LocalizedString.EN_US]: "Robot Driving Backwards" }, + description: { [LocalizedString.EN_US]: "Robot is driving backwards" }, + }, + + rightSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Right Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed right side of can 6", + }, + }, + + topSide: { + name: { [LocalizedString.EN_US]: "Robot Passed Top Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed top side of can 6", + }, + }, + + leftSide: { + name: { [LocalizedString.EN_US]: "Robot Passed left Side" }, + description: { + [LocalizedString.EN_US]: "Robot passed left side of can 6", + }, + }, + }, + success: { + exprs: { + // Driving Backwards events + driveBackwards: { + type: Expr.Type.Event, + eventId: "driveBackwards", + }, + // Passing side events + rightSide: { + type: Expr.Type.Event, + eventId: "rightSide", + }, + rightSideOnce: { + type: Expr.Type.Once, + argId: "rightSide", + }, + topSide: { + type: Expr.Type.Event, + eventId: "topSide", + }, + topSideOnce: { + type: Expr.Type.Once, + argId: "topSide", + }, + leftSide: { + type: Expr.Type.Event, + eventId: "leftSide", + }, + leftSideOnce: { + type: Expr.Type.Once, + argId: "leftSide", + }, + + // Intersects Events + can6Intersects: { + type: Expr.Type.Event, + eventId: "can6Intersects", + }, + + // Upright Events + can6Upright: { + type: Expr.Type.Event, + eventId: "can6Upright", + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUpright: { + type: Expr.Type.And, + argIds: ["can6Intersects", "can6Upright"], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + "driveBackwards", + "IntersectsUpright", + "startingBox", + "rightSideOnce", + "topSideOnce", + "leftSideOnce", + ], + }, + }, + rootId: "completion", + }, + sceneId: "jbc2c", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc2d.ts b/src/simulator/definitions/challenges/jbc2d.ts new file mode 100644 index 00000000..f31a908d --- /dev/null +++ b/src/simulator/definitions/challenges/jbc2d.ts @@ -0,0 +1,187 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 2D' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 2C: Ring Around the Can and Back It Up`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + can6Intersects: { + name: { [LocalizedString.EN_US]: 'Can 6 Intersects' }, + description: { [LocalizedString.EN_US]: 'Can 6 intersects circle 6' }, + }, + + can6Upright: { + name: { [LocalizedString.EN_US]: 'Can 6 Upright' }, + description: { [LocalizedString.EN_US]: 'Can 6 upright on circle 6' }, + }, + + returnStartBox1: { + name: { [LocalizedString.EN_US]: 'Robot Rentered Start 1' }, + description: { + [LocalizedString.EN_US]: + 'Robot reentered starting box after going forwards', + }, + }, + + returnStartBox2: { + name: { [LocalizedString.EN_US]: 'Robot Rentered Start 2' }, + description: { + [LocalizedString.EN_US]: + 'Robot reentered starting box after going backwards', + }, + }, + + driveBackwards: { + name: { [LocalizedString.EN_US]: 'Robot Driving Backwards' }, + description: { [LocalizedString.EN_US]: 'Robot is driving backwards' }, + }, + driveForwards: { + name: { [LocalizedString.EN_US]: 'Robot Driving Forwards' }, + description: { [LocalizedString.EN_US]: 'Robot is driving forwards' }, + }, + + rightSide: { + name: { [LocalizedString.EN_US]: 'Robot Passed Right Side' }, + description: { + [LocalizedString.EN_US]: 'Robot passed right side of can 6', + }, + }, + + topSide: { + name: { [LocalizedString.EN_US]: 'Robot Passed Top Side' }, + description: { + [LocalizedString.EN_US]: 'Robot passed top side of can 6', + }, + }, + + leftSide: { + name: { [LocalizedString.EN_US]: 'Robot Passed left Side' }, + description: { + [LocalizedString.EN_US]: 'Robot passed left side of can 6', + }, + }, + }, + success: { + exprs: { + // Driving Backwards events + driveBackwards: { + type: Expr.Type.Event, + eventId: 'driveBackwards', + }, + driveBackwardsOnce: { + type: Expr.Type.Once, + argId: 'driveBackwards', + }, + driveForwards: { + type: Expr.Type.Event, + eventId: 'driveForwards', + }, + driveForwardsOnce: { + type: Expr.Type.Once, + argId: 'driveForwards', + }, + driving: { + type: Expr.Type.And, + argIds: ['driveForwardsOnce', 'driveBackwardsOnce'], + }, + + // Passing side events + rightSide: { + type: Expr.Type.Event, + eventId: 'rightSide', + }, + rightSideOnce: { + type: Expr.Type.Once, + argId: 'rightSide', + }, + topSide: { + type: Expr.Type.Event, + eventId: 'topSide', + }, + topSideOnce: { + type: Expr.Type.Once, + argId: 'topSide', + }, + leftSide: { + type: Expr.Type.Event, + eventId: 'leftSide', + }, + leftSideOnce: { + type: Expr.Type.Once, + argId: 'leftSide', + }, + + // Intersects Events + can6Intersects: { + type: Expr.Type.Event, + eventId: 'can6Intersects', + }, + + // Upright Events + can6Upright: { + type: Expr.Type.Event, + eventId: 'can6Upright', + }, + + // Start Box Events + + returnStartBox1: { + type: Expr.Type.Event, + eventId: 'returnStartBox1', + }, + returnStartBox1Once: { + type: Expr.Type.Once, + argId: 'returnStartBox1', + }, + returnStartBox2: { + type: Expr.Type.Event, + eventId: 'returnStartBox2', + }, + returnStartBox2Once: { + type: Expr.Type.Once, + argId: 'returnStartBox2', + }, + + startingBox: { + type: Expr.Type.And, + argIds: ['returnStartBox1Once', 'returnStartBox2Once'], + }, + + // Intersects and upright logic + IntersectsUpright: { + type: Expr.Type.And, + argIds: ['can6Intersects', 'can6Upright'], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + 'driving', + 'IntersectsUpright', + 'startingBox', + 'rightSideOnce', + 'topSideOnce', + 'leftSideOnce', + ], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc2d', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc3.ts b/src/simulator/definitions/challenges/jbc3.ts new file mode 100644 index 00000000..464917ee --- /dev/null +++ b/src/simulator/definitions/challenges/jbc3.ts @@ -0,0 +1,94 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 3' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 3: Precision Parking`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + touchGarageLines: { + name: { [LocalizedString.EN_US]: 'Robot Touched Garage Lines' }, + description: { + [LocalizedString.EN_US]: 'Robot touched garage boundaries', + }, + }, + singleGarageRun1: { + name: { [LocalizedString.EN_US]: 'Robot Parked in One Garage' }, + description: { + [LocalizedString.EN_US]: 'Robot parked in only one garage', + }, + }, + singleGarageRun2: { + name: { [LocalizedString.EN_US]: 'Robot Parked in Different Garage' }, + description: { + [LocalizedString.EN_US]: 'Robot parked in a different garage', + }, + }, + + returnStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Returned Start' }, + description: { [LocalizedString.EN_US]: 'Robot returned to starting box' }, + }, + }, + success: { + exprs: { + // Garage Events + touchGarageLines: { + type: Expr.Type.Event, + eventId: 'touchGarageLines', + }, + touchGarageLinesNot: { + type: Expr.Type.Not, + argId: 'touchGarageLines', + }, + singleGarageRun1: { + type: Expr.Type.Event, + eventId: 'singleGarageRun1', + }, + singleGarageRun1Once: { + type: Expr.Type.Once, + argId: 'singleGarageRun1', + }, + singleGarageRun2: { + type: Expr.Type.Event, + eventId: 'singleGarageRun2', + }, + singleGarageRun2Once: { + type: Expr.Type.Once, + argId: 'singleGarageRun2', + }, + + + // Start Box Events + returnStartBox: { + type: Expr.Type.Event, + eventId: 'returnStartBox', + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: 'returnStartBox', + }, + + completion: { + type: Expr.Type.And, + argIds: ['singleGarageRun1Once', 'returnStartBoxOnce','singleGarageRun2Once', 'touchGarageLinesNot'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc3', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc4.ts b/src/simulator/definitions/challenges/jbc4.ts new file mode 100644 index 00000000..b39ec0ad --- /dev/null +++ b/src/simulator/definitions/challenges/jbc4.ts @@ -0,0 +1,131 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 4" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 4: Figure Eight`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can4Intersects: { + name: { [LocalizedString.EN_US]: "Can 4 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 4 intersects circle 4" }, + }, + can9Intersects: { + name: { [LocalizedString.EN_US]: "Can 9 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 9 intersects circle 9" }, + }, + + can4Upright: { + name: { [LocalizedString.EN_US]: "Can 4 Upright" }, + description: { [LocalizedString.EN_US]: "Can 4 upright on circle 4" }, + }, + can9Upright: { + name: { [LocalizedString.EN_US]: "Can 9 Upright" }, + description: { [LocalizedString.EN_US]: "Can 9 upright on circle 9" }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + + figureEight: { + name: { [LocalizedString.EN_US]: "Robot Figure Eight" }, + description: { + [LocalizedString.EN_US]: "Robot did a figure eight around cans 4 and 9", + }, + }, + }, + success: { + exprs: { + // Figure Eight Event + figureEight: { + type: Expr.Type.Event, + eventId: "figureEight", + }, + figureEightOnce: { + type: Expr.Type.Once, + argId: "figureEight", + }, + + // Intersects Events + can4Intersects: { + type: Expr.Type.Event, + eventId: "can4Intersects", + }, + can9Intersects: { + type: Expr.Type.Event, + eventId: "can9Intersects", + }, + + // Upright Events + can4Upright: { + type: Expr.Type.Event, + eventId: "can4Upright", + }, + can9Upright: { + type: Expr.Type.Event, + eventId: "can9Upright", + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUpright4: { + type: Expr.Type.And, + argIds: ["can4Intersects", "can4Upright"], + }, + IntersectsUpright9: { + type: Expr.Type.And, + argIds: ["can9Intersects", "can9Upright"], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: ["IntersectsUpright4", "IntersectsUpright9", "startingBox","figureEightOnce"], + }, + }, + rootId: "completion", + }, + sceneId: "jbc4", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc4b.ts b/src/simulator/definitions/challenges/jbc4b.ts new file mode 100644 index 00000000..43344e26 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc4b.ts @@ -0,0 +1,193 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 4B" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 4B: Barrel Racing`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can5Intersects: { + name: { [LocalizedString.EN_US]: "Can 5 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 5 intersects circle 5" }, + }, + can8Intersects: { + name: { [LocalizedString.EN_US]: "Can 8 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 8 intersects circle 8" }, + }, + can9Intersects: { + name: { [LocalizedString.EN_US]: "Can 9 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 9 intersects circle 9" }, + }, + + can5Upright: { + name: { [LocalizedString.EN_US]: "Can 5 Upright" }, + description: { [LocalizedString.EN_US]: "Can 5 upright on circle 5" }, + }, + can8Upright: { + name: { [LocalizedString.EN_US]: "Can 8 Upright" }, + description: { [LocalizedString.EN_US]: "Can 8 upright on circle 8" }, + }, + can9Upright: { + name: { [LocalizedString.EN_US]: "Can 9 Upright" }, + description: { [LocalizedString.EN_US]: "Can 9 upright on circle 9" }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + + clockwise8: { + name: { [LocalizedString.EN_US]: "Can 8 Clockwise" }, + description: { + [LocalizedString.EN_US]: "Robot drove clockwise around can 8", + }, + }, + counterClockwise5: { + name: { [LocalizedString.EN_US]: "Can 5 Counter Clockwise" }, + description: { + [LocalizedString.EN_US]: "Robot drove counter clockwise around can 5", + }, + }, + counterClockwise9: { + name: { [LocalizedString.EN_US]: "Can 9 Counter Clockwise" }, + description: { + [LocalizedString.EN_US]: "Robot drove counter clockwise around can 9", + }, + }, + }, + success: { + exprs: { + // Clockwise Events + clockwise8: { + type: Expr.Type.Event, + eventId: "clockwise8", + }, + clockwise8Once: { + type: Expr.Type.Once, + argId: "clockwise8", + }, + + // Counter Clockwise Events + counterClockwise5: { + type: Expr.Type.Event, + eventId: "counterClockwise5", + }, + counterClockwise5Once: { + type: Expr.Type.Once, + argId: "counterClockwise5", + }, + counterClockwise9: { + type: Expr.Type.Event, + eventId: "counterClockwise9", + }, + counterClockwise9Once: { + type: Expr.Type.Once, + argId: "counterClockwise9", + }, + + clockMovements: { + type: Expr.Type.And, + argIds: ["clockwise8Once", "counterClockwise5Once","counterClockwise9Once"], + }, + + + // Intersects Events + can5Intersects: { + type: Expr.Type.Event, + eventId: "can5Intersects", + }, + can8Intersects: { + type: Expr.Type.Event, + eventId: "can8Intersects", + }, + can9Intersects: { + type: Expr.Type.Event, + eventId: "can9Intersects", + }, + + // Upright Events + can5Upright: { + type: Expr.Type.Event, + eventId: "can5Upright", + }, + can8Upright: { + type: Expr.Type.Event, + eventId: "can8Upright", + }, + can9Upright: { + type: Expr.Type.Event, + eventId: "can9Upright", + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUpright5: { + type: Expr.Type.And, + argIds: ["can5Intersects", "can5Upright"], + }, + IntersectsUpright8: { + type: Expr.Type.And, + argIds: ["can8Intersects", "can8Upright"], + }, + IntersectsUpright9: { + type: Expr.Type.And, + argIds: ["can9Intersects", "can9Upright"], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: [ + "IntersectsUpright5", + "IntersectsUpright8", + "IntersectsUpright9", + "startingBox", + "clockMovements" + ], + }, + }, + rootId: "completion", + }, + sceneId: "jbc4b", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc5.ts b/src/simulator/definitions/challenges/jbc5.ts new file mode 100644 index 00000000..4e2a1123 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc5.ts @@ -0,0 +1,133 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 5' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 5: Dance Party`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + clockwise360: { + name: { [LocalizedString.EN_US]: 'Robot 360 Clockwise' }, + description: { + [LocalizedString.EN_US]: 'Robot turned 360 degrees clockwise', + }, + }, + counterClockwise360: { + name: { [LocalizedString.EN_US]: 'Robot 360 Counter Clockwise' }, + description: { + [LocalizedString.EN_US]: 'Robot turned 360 degrees counter clockwise', + }, + }, + driveForward: { + name: { [LocalizedString.EN_US]: 'Robot Drove Forward' }, + description: { + [LocalizedString.EN_US]: 'Robot drove forward', + }, + }, + driveBackward: { + name: { [LocalizedString.EN_US]: 'Robot Drove Backward' }, + description: { + [LocalizedString.EN_US]: 'Robot drove backward', + }, + }, + waveServo: { + name: { [LocalizedString.EN_US]: 'Robot Wave Servo' }, + description: { + [LocalizedString.EN_US]: 'Robot waved servo up and down at least once', + }, + }, + }, + success: { + exprs: { + // Waving Event + waveServo: { + type: Expr.Type.Event, + eventId: 'waveServo', + }, + waveServoOnce: { + type: Expr.Type.Once, + argId: 'waveServo', + }, + + // Turning Events + clockwise360: { + type: Expr.Type.Event, + eventId: 'clockwise360', + }, + clockwise360Once: { + type: Expr.Type.Once, + argId: 'clockwise360', + }, + counterClockwise360: { + type: Expr.Type.Event, + eventId: 'counterClockwise360', + }, + counterClockwise360Once: { + type: Expr.Type.Once, + argId: 'counterClockwise360', + }, + turning: { + type: Expr.Type.And, + argIds: ['clockwise360Once', 'counterClockwise360Once'], + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + + // Driving Events + driveForward: { + type: Expr.Type.Event, + eventId: 'driveForward', + }, + driveForwardOnce: { + type: Expr.Type.Once, + argId: 'driveForward', + }, + driveBackward: { + type: Expr.Type.Event, + eventId: 'driveBackward', + }, + driveBackwardOnce: { + type: Expr.Type.Once, + argId: 'driveBackward', + }, + + driving: { + type: Expr.Type.And, + argIds: ['driveForwardOnce', 'driveBackwardOnce'], + }, + + completion: { + type: Expr.Type.And, + argIds: ['leaveStartBoxOnce', 'turning', 'driving', 'waveServoOnce'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc5', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc6.ts b/src/simulator/definitions/challenges/jbc6.ts new file mode 100644 index 00000000..935907aa --- /dev/null +++ b/src/simulator/definitions/challenges/jbc6.ts @@ -0,0 +1,98 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 6" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 6: Load 'Em Up`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + can2Upright: { + name: { [LocalizedString.EN_US]: "Can 2 Upright" }, + description: { [LocalizedString.EN_US]: "Can 2 upright" }, + }, + can9Upright: { + name: { [LocalizedString.EN_US]: "Can 9 Upright" }, + description: { [LocalizedString.EN_US]: "Can 9 upright" }, + }, + can10Upright: { + name: { [LocalizedString.EN_US]: "Can 10 Upright" }, + description: { [LocalizedString.EN_US]: "Can 10 upright" }, + }, + + can2Intersects: { + name: { [LocalizedString.EN_US]: "Can 2 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 2 intersects green garage" }, + }, + can9Intersects: { + name: { [LocalizedString.EN_US]: "Can 9 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 9 intersects blue garage" }, + }, + can10Intersects: { + name: { [LocalizedString.EN_US]: "Can 10 Intersects" }, + description: { [LocalizedString.EN_US]: "Can 10 intersects yellow garage" }, + }, + }, + success: { + exprs: { + // Upright Events + can2Upright: { + type: Expr.Type.Event, + eventId: "can2Upright", + }, + can9Upright: { + type: Expr.Type.Event, + eventId: "can9Upright", + }, + can10Upright: { + type: Expr.Type.Event, + eventId: "can10Upright", + }, + cansUpright: { + type: Expr.Type.And, + argIds: ["can2Upright", "can9Upright", "can10Upright"], + }, + + + // Intersects Events + can2Intersects: { + type: Expr.Type.Event, + eventId: "can2Intersects", + }, + can9Intersects: { + type: Expr.Type.Event, + eventId: "can9Intersects", + }, + can10Intersects: { + type: Expr.Type.Event, + eventId: "can10Intersects", + }, + cansIntersects: { + type: Expr.Type.And, + argIds: ["can2Intersects", "can9Intersects", "can10Intersects"], + }, + + + // Success logic + completion: { + type: Expr.Type.And, + argIds: ["cansUpright", "cansIntersects"], + }, + }, + rootId: "completion", + }, + sceneId: "jbc6", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc6c.ts b/src/simulator/definitions/challenges/jbc6c.ts index d6a842e7..0bc62844 100644 --- a/src/simulator/definitions/challenges/jbc6c.ts +++ b/src/simulator/definitions/challenges/jbc6c.ts @@ -1,6 +1,7 @@ import Author from '../../../db/Author'; import Challenge from '../../../state/State/Challenge'; import Expr from '../../../state/State/Challenge/Expr'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; import tr from '@i18n'; @@ -12,9 +13,9 @@ export default { id: 'kipr' }, code: { - 'c': `#include `, - 'cpp': `#include `, - 'python': `from kipr import botball`, + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, }, defaultLanguage: 'c', events: { diff --git a/src/simulator/definitions/challenges/jbc7.ts b/src/simulator/definitions/challenges/jbc7.ts new file mode 100644 index 00000000..cf79b231 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc7.ts @@ -0,0 +1,147 @@ +import Author from "../../../db/Author"; +import Challenge from "../../../state/State/Challenge"; +import Expr from "../../../state/State/Challenge/Expr"; +import LocalizedString from "../../../util/LocalizedString"; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: "JBC Challenge 7" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 7: Bulldozer Mania`, + }, + author: { + type: Author.Type.Organization, + id: "kipr", + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: "c", + events: { + canAIntersects: { + name: { [LocalizedString.EN_US]: "Can A Intersects" }, + description: { [LocalizedString.EN_US]: "Can A behind start line" }, + }, + canBIntersects: { + name: { [LocalizedString.EN_US]: "Can B Intersects" }, + description: { [LocalizedString.EN_US]: "Can B behind start line" }, + }, + canCIntersects: { + name: { [LocalizedString.EN_US]: "Can C Intersects" }, + description: { [LocalizedString.EN_US]: "Can C behind start line" }, + }, + + canAUpright: { + name: { [LocalizedString.EN_US]: "Can A Upright" }, + description: { + [LocalizedString.EN_US]: "Can A upright behind start line", + }, + }, + canBUpright: { + name: { [LocalizedString.EN_US]: "Can B Upright" }, + description: { + [LocalizedString.EN_US]: "Can B upright behind start line", + }, + }, + canCUpright: { + name: { [LocalizedString.EN_US]: "Can C Upright" }, + description: { + [LocalizedString.EN_US]: "Can C upright behind start line", + }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: "Robot Left Start" }, + description: { [LocalizedString.EN_US]: "Robot left starting box" }, + }, + returnStartBox: { + name: { [LocalizedString.EN_US]: "Robot Rentered Start" }, + description: { [LocalizedString.EN_US]: "Robot reentered starting box" }, + }, + }, + success: { + exprs: { + // Intersects Events + canAIntersects: { + type: Expr.Type.Event, + eventId: "canAIntersects", + }, + canBIntersects: { + type: Expr.Type.Event, + eventId: "canBIntersects", + }, + canCIntersects: { + type: Expr.Type.Event, + eventId: "canCIntersects", + }, + + // Upright Events + canAUpright: { + type: Expr.Type.Event, + eventId: "canAUpright", + }, + canBUpright: { + type: Expr.Type.Event, + eventId: "canBUpright", + }, + canCUpright: { + type: Expr.Type.Event, + eventId: "canCUpright", + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: "leaveStartBox", + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: "leaveStartBox", + }, + returnStartBox: { + type: Expr.Type.Event, + eventId: "returnStartBox", + }, + returnStartBoxOnce: { + type: Expr.Type.Once, + argId: "returnStartBox", + }, + startingBox: { + type: Expr.Type.And, + argIds: ["leaveStartBoxOnce", "returnStartBoxOnce"], + }, + + // Intersects and upright logic + IntersectsUprightA: { + type: Expr.Type.And, + argIds: ["canAIntersects", "canAUpright"], + }, + IntersectsUprightB: { + type: Expr.Type.And, + argIds: ["canBIntersects", "canBUpright"], + }, + IntersectsUprightC: { + type: Expr.Type.And, + argIds: ["canCIntersects", "canCUpright"], + }, + AllIntersectsUpright: { + type: Expr.Type.And, + argIds: [ + "IntersectsUprightA", + "IntersectsUprightB", + "IntersectsUprightC", + ], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: ["startingBox", "AllIntersectsUpright"], + }, + }, + rootId: "completion", + }, + sceneId: "jbc7", +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc7b.ts b/src/simulator/definitions/challenges/jbc7b.ts new file mode 100644 index 00000000..5a5cd762 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc7b.ts @@ -0,0 +1,202 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 7B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 7B: Cover Your Bases`, + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + robotNoTouchFirst: { + name: { [LocalizedString.EN_US]: "Robot Doesn't Touch " }, + description: { + [LocalizedString.EN_US]: "Robot doesn't touch a can at the start", + }, + }, + canAIntersects: { + name: { [LocalizedString.EN_US]: 'Can A Intersects' }, + description: { [LocalizedString.EN_US]: 'Can A in a circle' }, + }, + canBIntersects: { + name: { [LocalizedString.EN_US]: 'Can B Intersects' }, + description: { [LocalizedString.EN_US]: 'Can B in a circle' }, + }, + canCIntersects: { + name: { [LocalizedString.EN_US]: 'Can C Intersects' }, + description: { [LocalizedString.EN_US]: 'Can C in a circle' }, + }, + canDIntersects: { + name: { [LocalizedString.EN_US]: 'Can D Intersects' }, + description: { [LocalizedString.EN_US]: 'Can D in a circle' }, + }, + canEIntersects: { + name: { [LocalizedString.EN_US]: 'Can E Intersects' }, + description: { [LocalizedString.EN_US]: 'Can E in a circle' }, + }, + + canAUpright: { + name: { [LocalizedString.EN_US]: 'Can A Upright' }, + description: { + [LocalizedString.EN_US]: 'Can A upright in a circle', + }, + }, + canBUpright: { + name: { [LocalizedString.EN_US]: 'Can B Upright' }, + description: { + [LocalizedString.EN_US]: 'Can B upright in a circle', + }, + }, + canCUpright: { + name: { [LocalizedString.EN_US]: 'Can C Upright' }, + description: { + [LocalizedString.EN_US]: 'Can C upright in a circle', + }, + }, + canDUpright: { + name: { [LocalizedString.EN_US]: 'Can D Upright' }, + description: { + [LocalizedString.EN_US]: 'Can D upright in a circle', + }, + }, + canEUpright: { + name: { [LocalizedString.EN_US]: 'Can E Upright' }, + description: { + [LocalizedString.EN_US]: 'Can E upright in a circle', + }, + }, + + leaveStartBox: { + name: { [LocalizedString.EN_US]: 'Robot Left Start' }, + description: { [LocalizedString.EN_US]: 'Robot left starting box' }, + }, + + }, + success: { + exprs: { + // Touch Events + robotNoTouchFirst: { + type: Expr.Type.Event, + eventId: 'robotNoTouchFirst', + }, + robotNoTouchFirstOnce: { + type: Expr.Type.Once, + argId: 'robotNoTouchFirst', + }, + robotNoTouchFirstOnceNot: { + type: Expr.Type.Not, + argId: 'robotNoTouchFirstOnce', + }, + + // Intersects Events + canAIntersects: { + type: Expr.Type.Event, + eventId: 'canAIntersects', + }, + canBIntersects: { + type: Expr.Type.Event, + eventId: 'canBIntersects', + }, + canCIntersects: { + type: Expr.Type.Event, + eventId: 'canCIntersects', + }, + canDIntersects: { + type: Expr.Type.Event, + eventId: 'canDIntersects', + }, + canEIntersects: { + type: Expr.Type.Event, + eventId: 'canEIntersects', + }, + + // Upright Events + canAUpright: { + type: Expr.Type.Event, + eventId: 'canAUpright', + }, + canBUpright: { + type: Expr.Type.Event, + eventId: 'canBUpright', + }, + canCUpright: { + type: Expr.Type.Event, + eventId: 'canCUpright', + }, + canDUpright: { + type: Expr.Type.Event, + eventId: 'canDUpright', + }, + canEUpright: { + type: Expr.Type.Event, + eventId: 'canEUpright', + }, + + // Start Box Events + leaveStartBox: { + type: Expr.Type.Event, + eventId: 'leaveStartBox', + }, + leaveStartBoxOnce: { + type: Expr.Type.Once, + argId: 'leaveStartBox', + }, + startingBox: { + type: Expr.Type.And, + argIds: ['leaveStartBoxOnce'], + }, + + // Intersects and upright logic + IntersectsUprightA: { + type: Expr.Type.And, + argIds: ['canAIntersects', 'canAUpright'], + }, + IntersectsUprightB: { + type: Expr.Type.And, + argIds: ['canBIntersects', 'canBUpright'], + }, + IntersectsUprightC: { + type: Expr.Type.And, + argIds: ['canCIntersects', 'canCUpright'], + }, + IntersectsUprightD: { + type: Expr.Type.And, + argIds: ['canDIntersects', 'canDUpright'], + }, + IntersectsUprightE: { + type: Expr.Type.And, + argIds: ['canEIntersects', 'canEUpright'], + }, + AllIntersectsUpright: { + type: Expr.Type.And, + argIds: [ + 'IntersectsUprightA', + 'IntersectsUprightB', + 'IntersectsUprightC', + 'IntersectsUprightD', + 'IntersectsUprightE', + ], + }, + + // Success Logic = Can A upright, intersects and touched + completion: { + type: Expr.Type.And, + argIds: ['robotNoTouchFirstOnceNot','startingBox', 'AllIntersectsUpright'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc7b', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc8.ts b/src/simulator/definitions/challenges/jbc8.ts new file mode 100644 index 00000000..27346a77 --- /dev/null +++ b/src/simulator/definitions/challenges/jbc8.ts @@ -0,0 +1,154 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 8' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 8: Serpentine', + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + start: { + name: { [LocalizedString.EN_US]: 'Robot Begins In start' }, + description: { [LocalizedString.EN_US]: 'Robot begins in starting box' }, + }, + passed1: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 1' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 1' }, + }, + passed2: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 2' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 2' }, + }, + passed3: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 3' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 3' }, + }, + passed4: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 4' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 4' }, + }, + passed5: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 5' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 5' }, + }, + passed6: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 6' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 6' }, + }, + passed7: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 7' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 7' }, + }, + passed8: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 8' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 8' }, + }, + }, + success: { + exprs: { + // Start Box Event + start: { + type: Expr.Type.Event, + eventId: 'start', + }, + startOnce: { + type: Expr.Type.Once, + argId: 'start', + }, + + // Passed Through Circles Events + passed1: { + type: Expr.Type.Event, + eventId: 'passed1', + }, + passed1Once: { + type: Expr.Type.Once, + argId: 'passed1', + }, + + passed2: { + type: Expr.Type.Event, + eventId: 'passed2', + }, + passed2Once: { + type: Expr.Type.Once, + argId: 'passed2', + }, + passed3: { + type: Expr.Type.Event, + eventId: 'passed3', + }, + passed3Once: { + type: Expr.Type.Once, + argId: 'passed3', + }, + passed4: { + type: Expr.Type.Event, + eventId: 'passed4', + }, + passed4Once: { + type: Expr.Type.Once, + argId: 'passed4', + }, + passed5: { + type: Expr.Type.Event, + eventId: 'passed5', + }, + passed5Once: { + type: Expr.Type.Once, + argId: 'passed5', + }, + passed6: { + type: Expr.Type.Event, + eventId: 'passed6', + }, + passed6Once: { + type: Expr.Type.Once, + argId: 'passed6', + }, + passed7: { + type: Expr.Type.Event, + eventId: 'passed7', + }, + passed7Once: { + type: Expr.Type.Once, + argId: 'passed7', + }, + passed8: { + type: Expr.Type.Event, + eventId: 'passed8', + }, + passed8Once: { + type: Expr.Type.Once, + argId: 'passed8', + }, + + + passedSerpentine: { + type: Expr.Type.And, + argIds: ["passed1Once", "passed2Once","passed3Once", "passed4Once", "passed5Once", "passed6Once", "passed7Once", "passed8Once"], + }, + + // Success logic + completion: { + type: Expr.Type.And, + argIds: ['startOnce', 'passedSerpentine'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc8', +} as Challenge; diff --git a/src/simulator/definitions/challenges/jbc8b.ts b/src/simulator/definitions/challenges/jbc8b.ts new file mode 100644 index 00000000..fec7ae4f --- /dev/null +++ b/src/simulator/definitions/challenges/jbc8b.ts @@ -0,0 +1,118 @@ +import Author from '../../../db/Author'; +import Challenge from '../../../state/State/Challenge'; +import Expr from '../../../state/State/Challenge/Expr'; +import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; + +export default { + name: { [LocalizedString.EN_US]: 'JBC Challenge 8B' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 8B: Serpentine Jr.', + }, + author: { + type: Author.Type.Organization, + id: 'kipr', + }, + code: { + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, + }, + defaultLanguage: 'c', + events: { + start: { + name: { [LocalizedString.EN_US]: 'Robot Begins In start' }, + description: { [LocalizedString.EN_US]: 'Robot begins in starting box' }, + }, + passed1: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 1' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 1' }, + }, + passed2: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 2' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 2' }, + }, + passed3: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 3' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 3' }, + }, + passed4: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 4' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 4' }, + }, + passed5: { + name: { [LocalizedString.EN_US]: 'Robot Touched Circle 5' }, + description: { [LocalizedString.EN_US]: 'Robot passed through circle 5' }, + }, + }, + success: { + exprs: { + // Start Box Event + start: { + type: Expr.Type.Event, + eventId: 'start', + }, + startOnce: { + type: Expr.Type.Once, + argId: 'start', + }, + + // Passed Through Circles Events + passed1: { + type: Expr.Type.Event, + eventId: 'passed1', + }, + passed1Once: { + type: Expr.Type.Once, + argId: 'passed1', + }, + + passed2: { + type: Expr.Type.Event, + eventId: 'passed2', + }, + passed2Once: { + type: Expr.Type.Once, + argId: 'passed2', + }, + passed3: { + type: Expr.Type.Event, + eventId: 'passed3', + }, + passed3Once: { + type: Expr.Type.Once, + argId: 'passed3', + }, + passed4: { + type: Expr.Type.Event, + eventId: 'passed4', + }, + passed4Once: { + type: Expr.Type.Once, + argId: 'passed4', + }, + passed5: { + type: Expr.Type.Event, + eventId: 'passed5', + }, + passed5Once: { + type: Expr.Type.Once, + argId: 'passed5', + }, + + + passedSerpentine: { + type: Expr.Type.And, + argIds: ["passed1Once", "passed2Once","passed3Once", "passed4Once", "passed5Once"], + }, + + // Success logic + completion: { + type: Expr.Type.And, + argIds: ['startOnce', 'passedSerpentine'], + }, + }, + rootId: 'completion', + }, + sceneId: 'jbc8b', +} as Challenge; diff --git a/src/simulator/definitions/challenges/test.ts b/src/simulator/definitions/challenges/test.ts index c94785c1..9dfc8d74 100644 --- a/src/simulator/definitions/challenges/test.ts +++ b/src/simulator/definitions/challenges/test.ts @@ -2,6 +2,7 @@ import Author from '../../../db/Author'; import Challenge from '../../../state/State/Challenge'; import Expr from '../../../state/State/Challenge/Expr'; import LocalizedString from '../../../util/LocalizedString'; +import ProgrammingLanguage from "../../../programming/compiler/ProgrammingLanguage"; export default { name: { [LocalizedString.EN_US]: 'Test' }, @@ -11,9 +12,9 @@ export default { id: 'kipr' }, code: { - 'c': `#include `, - 'cpp': `#include `, - 'python': `from kipr import botball`, + 'c': ProgrammingLanguage.DEFAULT_CODE.c, + 'cpp': ProgrammingLanguage.DEFAULT_CODE.cpp, + 'python': ProgrammingLanguage.DEFAULT_CODE.python, }, defaultLanguage: 'c', events: { diff --git a/src/simulator/definitions/scenes/jbc1.ts b/src/simulator/definitions/scenes/jbc1.ts index 53a37459..5bf8a851 100644 --- a/src/simulator/definitions/scenes/jbc1.ts +++ b/src/simulator/definitions/scenes/jbc1.ts @@ -1,20 +1,184 @@ import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; - +import { Distance } from "../../../util"; +import Script from '../../../state/State/Scene/Script'; +import { Color } from '../../../state/State/Scene/Color'; import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; -import tr from '@i18n'; - const baseScene = createBaseSceneSurfaceA(); +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can9) is intersecting circle9, the circle glows + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Can 9 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('canAIntersects', visible); + setNodeVisible('circle9', visible); +}, 'circle9'); + +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const robotTouches = ` +scene.onBind = nodeId => { + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + console.log('Can A touched!', otherNodeId, point); + scene.setChallengeEventValue(nodeId + 'Touched', true); + }, 'robot'); +}; +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +// let startTime = Date.now(); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +// const startingOrientationInv = (nodeId) => Quaternion.inverse(RotationwUnits.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + +scene.addOnRenderListener(() => { + // const currTime = Date.now(); + // const timeDiff = currTime - startTime; + const upright9 = yAngle('can9') < 5; + // if(timeDiff > 1000) { + // console.log('can9 angle: ', yAngle('can9')); + // startTime = currTime; + // } + scene.setChallengeEventValue('canAUpright', upright9); + +}); +`; + export const JBC_1: Scene = { ...baseScene, - - name: tr('JBC 1'), - description: tr('Junior Botball Challenge 1: Tag, You\'re It!'), + name: { [LocalizedString.EN_US]: 'JBC 1' }, + description: { [LocalizedString.EN_US]: `Junior Botball Challenge 1: Tag, You're It!` }, + scripts: { + 'circleIntersects': Script.ecmaScript('Circle Intersects', circleIntersects), + 'uprightCans': Script.ecmaScript('Upright Cans', uprightCans), + 'robotTouches': Script.ecmaScript('Robot Touches', robotTouches), + 'leftStartBox': Script.ecmaScript('Robot Left Start', leftStartBox), + 'enterStartBox': Script.ecmaScript('Robot Reentered Start',enterStartBox), + }, + geometry: { + ...baseScene.geometry, + 'circle9_geom': { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + 'mainSurface_geom': { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + 'startBox_geom': { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + }, nodes: { ...baseScene.nodes, - can9: createCanNode(9), - }, + 'mainSurface': { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0) + } + }, + }, + 'circle9': { + type: 'object', + geometryId: 'circle9_geom', + name: { [LocalizedString.EN_US]: 'Circle 9' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + 'startBox': { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can9: { + ...createCanNode(9, { x: Distance.centimeters(0), y: Distance.centimeters(0), z: Distance.centimeters(85.4) }), + scriptIds: ['robotTouches'] + } + + } + }; diff --git a/src/simulator/definitions/scenes/jbc10.ts b/src/simulator/definitions/scenes/jbc10.ts index 8c0f5b6f..e813bb20 100644 --- a/src/simulator/definitions/scenes/jbc10.ts +++ b/src/simulator/definitions/scenes/jbc10.ts @@ -1,19 +1,173 @@ -import Scene from "../../../state/State/Scene"; -import { Distance } from "../../../util"; +import Scene from '../../../state/State/Scene'; +import { ReferenceFramewUnits } from '../../../util/math/unitMath'; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; - +import Script from '../../../state/State/Scene/Script'; import { createBaseSceneSurfaceB, createCanNode } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from '../../../state/State/Scene/Color'; const baseScene = createBaseSceneSurfaceB(); +const lineBIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// If the robot touches Line B, failed challenge + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot Touching Line B!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('robotTouchingLine', visible); +}, 'lineB'); + +`; + + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + +scene.addOnRenderListener(() => { + + const upright1 = yAngle('can1') < 5; + scene.setChallengeEventValue('can1Upright', upright1); + +}); +`; +const ROBOT_ORIGIN: ReferenceFramewUnits = { + ...baseScene.nodes['robot'].origin, + position: { + ...baseScene.nodes['robot'].origin.position, + x: Distance.centimeters(-15), + }, +}; export const JBC_10: Scene = { ...baseScene, - name: tr('JBC 10'), - description: tr('Junior Botball Challenge 10: Solo Joust'), + name: { [LocalizedString.EN_US]: 'JBC 10' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 10: Solo Joust', + }, + scripts: { + uprightCans: Script.ecmaScript('Upright Cans', uprightCans), + leftStartBox: Script.ecmaScript('Robot Left Start', leftStartBox), + lineBIntersects: Script.ecmaScript('Robot Line B', lineBIntersects), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(1.77), + y: Distance.centimeters(0.1), + z: Distance.centimeters(30), + }, + }, + lineB_geom: { + type: 'box', + size: { + x: Distance.centimeters(0.5), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + }, nodes: { ...baseScene.nodes, - 'can1': createCanNode(1, { x: Distance.centimeters(11), y: Distance.centimeters(0), z: Distance.centimeters(91) }), - } -}; \ No newline at end of file + robot: { + ...baseScene.nodes['robot'], + startingOrigin: ROBOT_ORIGIN, + origin: ROBOT_ORIGIN, + }, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-90), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-3), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + lineB: { + type: 'object', + geometryId: 'lineB_geom', + name: { [LocalizedString.EN_US]: 'Line B' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can1: { + ...createCanNode(1,{ + x: Distance.centimeters(11), + y: Distance.centimeters(0), + z: Distance.centimeters(91), + }), + scriptIds: ["startBoxIntersects", "uprightCans", "lineBIntersects"], + + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc10b.ts b/src/simulator/definitions/scenes/jbc10b.ts index 65efa13d..6f0b4975 100644 --- a/src/simulator/definitions/scenes/jbc10b.ts +++ b/src/simulator/definitions/scenes/jbc10b.ts @@ -1,19 +1,77 @@ import Scene from "../../../state/State/Scene"; import { Distance } from "../../../util"; import LocalizedString from '../../../util/LocalizedString'; - +import { Color } from '../../../state/State/Scene/Color'; import { createBaseSceneSurfaceB, createCanNode } from './jbcBase'; -import tr from '@i18n'; - const baseScene = createBaseSceneSurfaceB(); export const JBC_10B: Scene = { ...baseScene, - name: tr('JBC 10B'), - description: tr('Junior Botball Challenge 10: Solo Joust Jr.'), + name: { [LocalizedString.EN_US]: 'JBC 10B' }, + description: { [LocalizedString.EN_US]: 'Junior Botball Challenge 10: Solo Joust Jr.' }, nodes: { ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(-90), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-3), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + lineB: { + type: 'object', + geometryId: 'lineB_geom', + name: { [LocalizedString.EN_US]: 'Line B' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, 'can1': createCanNode(1, { x: Distance.centimeters(-13), y: Distance.centimeters(0), z: Distance.centimeters(17) }), // green line 'can2': createCanNode(2, { x: Distance.centimeters(-17), y: Distance.centimeters(0), z: Distance.centimeters(41) }), // red line 'can3': createCanNode(3, { x: Distance.centimeters(11.5), y: Distance.centimeters(0), z: Distance.centimeters(51) }), // yellow line diff --git a/src/simulator/definitions/scenes/jbc12.ts b/src/simulator/definitions/scenes/jbc12.ts index c0eb326c..0d5f9063 100644 --- a/src/simulator/definitions/scenes/jbc12.ts +++ b/src/simulator/definitions/scenes/jbc12.ts @@ -1,21 +1,231 @@ -import Scene from "../../../state/State/Scene"; -import { Distance } from "../../../util"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; +import Script from '../../../state/State/Scene/Script'; +import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import { Distance } from '../../../util'; -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. -const baseScene = createBaseSceneSurfaceA(); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + +scene.addOnRenderListener(() => { + // const currTime = Date.now(); + // const timeDiff = currTime - startTime; + const upright2 = yAngle('can2') < 5; + const upright9 = yAngle('can9') < 5; + const upright10 = yAngle('can10') < 5; + + scene.setChallengeEventValue('can2Upright', upright2); + scene.setChallengeEventValue('can9Upright', upright9); + scene.setChallengeEventValue('can10Upright', upright10); +}); +`; + + +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can2 in green garage) is intersecting circle4, the circle glows + +scene.addOnIntersectionListener('can2', (type, otherNodeId) => { + console.log('Can 2 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can2Intersects', visible); + setNodeVisible('circle2', visible); +}, 'circle2'); +// When the can (can9 in blue garage) is intersecting circle9, the circle glows + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Can 9 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can9Intersects', visible); + setNodeVisible('circle9', visible); +}, 'circle9'); + +// When the can (can10 in yellow garage) is intersecting circle10, the circle glows + +scene.addOnIntersectionListener('can10', (type, otherNodeId) => { + console.log('Can 10 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can10Intersects', visible); + setNodeVisible('circle10', visible); +}, 'circle10'); + +`; export const JBC_12: Scene = { ...baseScene, - name: tr('JBC 12'), - description: tr('Junior Botball Challenge 12: Unload \'Em'), + name: { [LocalizedString.EN_US]: 'JBC 12' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 12: Unload 'Em`, + }, + + scripts: { + uprightCans: Script.ecmaScript('Upright Cans', uprightCans), + circleIntersects: Script.ecmaScript('Circle Intersects', circleIntersects), + }, + geometry: { + ...baseScene.geometry, + circle_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + }, nodes: { ...baseScene.nodes, - 'can1': createCanNode(1, { x: Distance.centimeters(0), y: Distance.centimeters(0), z: Distance.centimeters(53.3) }), - 'can2': createCanNode(2, { x: Distance.centimeters(18.5), y: Distance.centimeters(0), z: Distance.centimeters(78) }), - 'can3': createCanNode(3, { x: Distance.centimeters(-12.3), y: Distance.centimeters(0), z: Distance.centimeters(93.9) }), - } -}; \ No newline at end of file + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle2: { + type: "object", + geometryId: "circle_geom", + name: { [LocalizedString.EN_US]: "Circle 2" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28.8), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + circle9: { + type: "object", + geometryId: "circle_geom", + name: { [LocalizedString.EN_US]: "Circle 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 9 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle10: { + type: "object", + geometryId: "circle_geom", + name: { [LocalizedString.EN_US]: "Circle 10" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(19.3),// can 10 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can2: { + ...createCanNode(2, { + x: Distance.centimeters(0), + y: Distance.centimeters(0), + z: Distance.centimeters(53.3), + }), + scriptIds: ["uprightCans", "circleIntersects"], + }, + can10: { + ...createCanNode(9, { + x: Distance.centimeters(18.5), + y: Distance.centimeters(0), + z: Distance.centimeters(78), + }), + scriptIds: ["uprightCans", "circleIntersects"], + }, + can9: { + ...createCanNode(10, { + x: Distance.centimeters(-12.3), + y: Distance.centimeters(0), + z: Distance.centimeters(93.9), + }), + scriptIds: ["uprightCans", "circleIntersects"], + }, + + }, +}; diff --git a/src/simulator/definitions/scenes/jbc13.ts b/src/simulator/definitions/scenes/jbc13.ts index fc969211..6461f896 100644 --- a/src/simulator/definitions/scenes/jbc13.ts +++ b/src/simulator/definitions/scenes/jbc13.ts @@ -1,22 +1,225 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance , Angle } from "../../../util"; -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const garageIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When a can (can2, can5, can8, can10, can11) is intersecting a garage, the garage glows +let chosenGarage = []; +let garageCans = [] +let begin = 0; +scene.onBind = nodeId => { + + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + const visible = type === 'start'; + + //No chosen garage yet and enters + if(chosenGarage.length == 0){ + chosenGarage[0] = otherNodeId; + + setNodeVisible(chosenGarage[0], true); + } + + //If the garage the can moved into is the desired garage + if(otherNodeId == chosenGarage[0] && type === 'start'){ + console.log(nodeId +' placed!', type, otherNodeId); + garageCans.push(nodeId); + scene.setChallengeEventValue(nodeId + 'Intersects', true); + if(chosenGarage.length > 0){ + setNodeVisible(chosenGarage[0], true); + } + } + + //If a previously entered can leaves desired garage + if(otherNodeId == chosenGarage[0] && type === 'end' && (garageCans.includes(nodeId) == true)){ + const removeIndex = garageCans.indexOf(nodeId); + const x = garageCans.splice(removeIndex,1); + scene.setChallengeEventValue(nodeId + 'Intersects', false); + + } + + //If a previously enterted can in desired garage enters a different garage + else if(otherNodeId != chosenGarage[0] && (garageCans.includes(nodeId) == true)){ + const removeIndex = garageCans.indexOf(otherNodeId); + const x = garageCans.splice(removeIndex,1); + + + } + + + //If there aren't any cans in a garage, reset chosen garage + if(garageCans.length == 0){ + setNodeVisible(chosenGarage[0], false); + chosenGarage.pop(); + + } + + + console.log("Chosen Garage: " + chosenGarage); + console.log("Cans In Chosen Garage: " + garageCans); + }, ['yellowGarage','blueGarage','greenGarage']); + +} + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); -const baseScene = createBaseSceneSurfaceA(); + +scene.addOnRenderListener(() => { + const upright2 = yAngle('can2') < 5; + const upright5 = yAngle('can5') < 5; + const upright8 = yAngle('can8') < 5; + const upright10 = yAngle('can10') < 5; + const upright11 = yAngle('can11') < 5; + + scene.setChallengeEventValue('can2Upright', upright2); + scene.setChallengeEventValue('can5Upright', upright5); + scene.setChallengeEventValue('can8Upright', upright8); + scene.setChallengeEventValue('can10Upright', upright10); + scene.setChallengeEventValue('can11Upright', upright11); +}); +`; export const JBC_13: Scene = { ...baseScene, - name: tr('JBC 13'), - description: tr('Junior Botball Challenge 13: Clean the Mat'), + name: { [LocalizedString.EN_US]: 'JBC 13' }, + description: { [LocalizedString.EN_US]: `Junior Botball Challenge 13: Clean the Mat` }, + scripts: { + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + garageIntersects: Script.ecmaScript("Garage Intersects", garageIntersects), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + greenGarage_geom: { + type: "box", + size: { + x: Distance.centimeters(20), + y: Distance.centimeters(0.1), + z: Distance.centimeters(20), + }, + }, + + blueGarage_geom: { + type: "box", + size: { + x: Distance.centimeters(16), + y: Distance.centimeters(0.1), + z: Distance.centimeters(16), + }, + }, + yellowGarage_geom: { + type: "box", + size: { + x: Distance.centimeters(16), + y: Distance.centimeters(0.1), + z: Distance.centimeters(18), + }, + }, + }, nodes: { ...baseScene.nodes, - 'can2': createCanNode(2), - 'can5': createCanNode(5), - 'can8': createCanNode(8), - 'can10': createCanNode(10), - 'can11': createCanNode(11), + greenGarage: { + type: "object", + geometryId: "greenGarage_geom", + name: { [LocalizedString.EN_US]: "Green Garage" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + blueGarage: { + type: "object", + geometryId: "blueGarage_geom", + name: { [LocalizedString.EN_US]: "Blue Garage" }, + visible: true, + origin: { + position: { + x: Distance.centimeters(-13.4), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96), + }, + // orientation: { + + // type: 'euler', + // x: Angle.degrees(0), + // y: Angle.degrees(-45), + // z: Angle.degrees(0), + // }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + + + }, + yellowGarage: { + type: "object", + geometryId: "yellowGarage_geom", + name: { [LocalizedString.EN_US]: "Yellow Garage" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18.8), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(78), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + can2: { ...createCanNode(2), scriptIds: ["garageIntersects","uprightCans"] }, + can5: { ...createCanNode(5), scriptIds: ["garageIntersects","uprightCans"] }, + can8: { ...createCanNode(8), scriptIds: ["garageIntersects","uprightCans"] }, + can10: { ...createCanNode(10), scriptIds: ["garageIntersects","uprightCans"] }, + can11: { ...createCanNode(11), scriptIds: ["garageIntersects","uprightCans"] }, } }; \ No newline at end of file diff --git a/src/simulator/definitions/scenes/jbc15b.ts b/src/simulator/definitions/scenes/jbc15b.ts index 3ea814c1..67b9138d 100644 --- a/src/simulator/definitions/scenes/jbc15b.ts +++ b/src/simulator/definitions/scenes/jbc15b.ts @@ -1,19 +1,69 @@ -import Scene from "../../../state/State/Scene"; -import { ReferenceFramewUnits, RotationwUnits } from "../../../util/math/unitMath"; -import { Distance, Mass } from "../../../util"; +import Scene from '../../../state/State/Scene'; +import { ReferenceFramewUnits, RotationwUnits } from '../../../util/math/unitMath'; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; - -import { createBaseSceneSurfaceA } from './jbcBase'; +import Script from '../../../state/State/Scene/Script'; +import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; import tr from '@i18n'; const baseScene = createBaseSceneSurfaceA(); +const bumpReam = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); +let count = 0; +let position = 0; + +scene.onBind = nodeId => { + + if(count == 3){ + count = 0; + } + scene.addOnCollisionListener('robot', (otherNodeId, point) => { + + //If front bumper is pressed + if(scene.nodes['robot'].state.digitalValues[0] === true) { + count = 1; + scene.setChallengeEventValue('driveForwardTouch', true); + console.log("Touched 1st ream"); + } + + //If either left or right back bumpers are pressed and front touch sensor was pressed first + if((scene.nodes['robot'].state.digitalValues[1] === true || scene.nodes['robot'].state.digitalValues[2] === true) && count == 1) + { + count = 2; + scene.setChallengeEventValue('driveBackwardTouch', true); + console.log("Touched 2nd ream"); + } + + + }, ['ream1','ream2',]); + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + //If touching first (front) and second (back) paper reams then going to circle 2 + if(count == 2){ + const visible = type === 'start'; + console.log('Robot intersecting circle 2!', type, otherNodeId); + scene.setChallengeEventValue('driveForward2', visible); + setNodeVisible('circle2', visible); + count = 3; + } + }, 'circle2'); + +}; + +`; + const ROBOT_ORIGIN: ReferenceFramewUnits = { ...baseScene.nodes['robot'].origin, position: { ...baseScene.nodes['robot'].origin.position, - z: Distance.centimeters(7) + z: Distance.centimeters(7), }, }; @@ -33,7 +83,7 @@ const REAM2_ORIGIN: ReferenceFramewUnits = { position: { x: Distance.centimeters(0), y: Distance.centimeters(5), - z: Distance.centimeters(-6.3), + z: Distance.centimeters(-12), }, orientation: RotationwUnits.AxisAngle.fromRaw({ axis: { x: 1, y: 0, z: 0 }, @@ -43,18 +93,67 @@ const REAM2_ORIGIN: ReferenceFramewUnits = { export const JBC_15B: Scene = { ...baseScene, - name: tr('JBC 15B'), - description: tr('Junior Botball Challenge 15B: Bump Bump'), + name: { [LocalizedString.EN_US]: 'JBC 15B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 15B: Bump Bump`, + }, + scripts: { + bumpReam: Script.ecmaScript('Bump Ream', bumpReam), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + circle2_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + }, nodes: { ...baseScene.nodes, // The normal starting position of the robot doesn't leave room for the paper ream in the starting box // Start the robot forward a bit so that a ream fits behind it - 'robot': { + robot: { ...baseScene.nodes['robot'], startingOrigin: ROBOT_ORIGIN, origin: ROBOT_ORIGIN, }, - 'ream1': { + circle2: { + type: 'object', + geometryId: 'circle2_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28.8), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + ream1: { type: 'from-jbc-template', templateId: 'ream', name: tr('Paper Ream 1'), @@ -62,7 +161,7 @@ export const JBC_15B: Scene = { origin: REAM1_ORIGIN, visible: true, }, - 'ream2': { + ream2: { type: 'from-jbc-template', templateId: 'ream', name: tr('Paper Ream 2'), @@ -70,5 +169,18 @@ export const JBC_15B: Scene = { origin: REAM2_ORIGIN, visible: true, }, + can12: { // Created an invisible can to attach script + ...createCanNode( + 12, + { + x: Distance.centimeters(11), + y: Distance.centimeters(0), + z: Distance.centimeters(91), + }, + false, + false + ), + scriptIds: ['bumpReam'], + }, }, -}; \ No newline at end of file +}; diff --git a/src/simulator/definitions/scenes/jbc17.ts b/src/simulator/definitions/scenes/jbc17.ts index 53d17f8d..f2794375 100644 --- a/src/simulator/definitions/scenes/jbc17.ts +++ b/src/simulator/definitions/scenes/jbc17.ts @@ -1,15 +1,213 @@ -import Scene from "../../../state/State/Scene"; -import { Distance } from "../../../util"; +import Scene from '../../../state/State/Scene'; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; +import { ReferenceFramewUnits } from '../../../util/math/unitMath'; +import { createCanNode, createBaseSceneSurfaceB } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import Script from '../../../state/State/Scene/Script'; -import { createBaseSceneSurfaceB } from './jbcBase'; +const baseScene = createBaseSceneSurfaceB(); -import tr from '@i18n'; +const lineFollow = ` -const baseScene = createBaseSceneSurfaceB(); +scene.onBind = nodeId => { + let count = 0; + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + //Reset counter if robot in start box + if(otherNodeId == 'startBox' && type === 'start'){ + count = 0; + } + //1st checkpoint + if(otherNodeId == 'n1' && type === 'start' && count == 0){ + count = 1; + console.log("Robot passed checkpoint 1"); + } + //2nd checkpoint + else if (otherNodeId == 'n2' && type === 'start' && count == 1){ + count = 2; + console.log("Robot passed checkpoint 2 after checkpoint 1"); + } + //3rd checkpoint + else if(otherNodeId == 'n3' && type === 'start'&& count == 2){ + count = 3; + console.log("Robot passed checkpoint 3 after checkpoint 2"); + } + //Finish line after all other checkpoints + else if(otherNodeId == 'finishLine' && type === 'start' && count == 3){ + console.log("Robot completed the course!"); + scene.setChallengeEventValue('lineFollow', true); + } + + console.log("Count: " + count); + }, ['finishLine', 'n1', 'n2', 'n3', 'startBox']); +}; + +`; +const ROBOT_ORIGIN: ReferenceFramewUnits = { + ...baseScene.nodes['robot'].origin, + position: { + ...baseScene.nodes['robot'].origin.position, + x: Distance.centimeters(-15), + }, +}; export const JBC_17: Scene = { ...baseScene, - name: tr('JBC 17'), - description: tr('Junior Botball Challenge 17: Walk the Line'), -}; \ No newline at end of file + name: { [LocalizedString.EN_US]: 'JBC 17' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 17: Walk the Line', + }, + scripts: { + lineFollow: Script.ecmaScript('Line Follow', lineFollow), + }, + geometry: { + ...baseScene.geometry, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(1.22), + y: Distance.centimeters(0.1), + z: Distance.centimeters(10), + }, + }, + n_geom: { + type: 'cylinder', + radius: Distance.centimeters(1), + height: Distance.centimeters(0.1), + }, + finish_geom: { + type: 'box', + size: { + x: Distance.centimeters(25), + y: Distance.centimeters(0.1), + z: Distance.centimeters(3.54), + }, + }, + }, + nodes: { + ...baseScene.nodes, + robot: { + ...baseScene.nodes['robot'], + startingOrigin: ROBOT_ORIGIN, + origin: ROBOT_ORIGIN, + }, + finishLine: { + type: 'object', + geometryId: 'finish_geom', + name: { [LocalizedString.EN_US]: 'Finish Line' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Finish Line' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-70), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-18), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(61), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(105), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can12: { + // Created an invisible can to attach script + ...createCanNode( + 12, + { + x: Distance.centimeters(11), + y: Distance.centimeters(0), + z: Distance.centimeters(91), + }, + false, + false + ), + scriptIds: ['lineFollow'], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc17b.ts b/src/simulator/definitions/scenes/jbc17b.ts index 882f7ce0..40d6f940 100644 --- a/src/simulator/definitions/scenes/jbc17b.ts +++ b/src/simulator/definitions/scenes/jbc17b.ts @@ -1,19 +1,53 @@ import Scene from "../../../state/State/Scene"; import { ReferenceFramewUnits } from '../../../util/math/unitMath'; import { Distance } from "../../../util"; +import { createCanNode, createBaseSceneSurfaceB } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import Script from '../../../state/State/Scene/Script'; import LocalizedString from '../../../util/LocalizedString'; -import { createBaseSceneSurfaceB } from './jbcBase'; - import tr from '@i18n'; const baseScene = createBaseSceneSurfaceB(); +const lineFollow = ` + +scene.onBind = nodeId => { + let count = 0; + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + //Reset counter if robot in start box + if(otherNodeId == 'startBox' && type === 'start'){ + count = 0; + } + //1st checkpoint + if(otherNodeId == 'n1' && type === 'start' && count == 0){ + count = 1; + console.log("Robot passed checkpoint 1"); + } + //2nd checkpoint + else if (otherNodeId == 'n2' && type === 'start' && count == 1){ + count = 2; + console.log("Robot passed checkpoint 2 after checkpoint 1"); + } + + //Finish line after all other checkpoints + else if(otherNodeId == 'lineB' && type === 'start' && count == 2){ + console.log("Robot completed the course!"); + scene.setChallengeEventValue('lineFollow', true); + } + + console.log("Count: " + count); + }, ['lineB', 'n1', 'n2', 'n3', 'startBox']); + +}; + +`; const ROBOT_ORIGIN: ReferenceFramewUnits = { ...baseScene.nodes['robot'].origin, position: { ...baseScene.nodes['robot'].origin.position, - x: Distance.centimeters(16.5), + x: Distance.centimeters(-16.5), }, }; @@ -22,6 +56,33 @@ export const JBC_17B: Scene = { name: tr('JBC 17B'), description: tr('Junior Botball Challenge 17: Walk the Line II'), // Start the robot on the black tape + scripts: { + lineFollow: Script.ecmaScript('Line Follow', lineFollow), + }, + geometry: { + ...baseScene.geometry, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(1.22), + y: Distance.centimeters(0.1), + z: Distance.centimeters(10), + }, + }, + n_geom: { + type: 'cylinder', + radius: Distance.centimeters(1), + height: Distance.centimeters(0.1), + }, + lineB_geom: { + type: 'box', + size: { + x: Distance.centimeters(0.5), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + }, nodes: { ...baseScene.nodes, 'robot': { @@ -29,5 +90,122 @@ export const JBC_17B: Scene = { startingOrigin: ROBOT_ORIGIN, origin: ROBOT_ORIGIN }, - } -}; \ No newline at end of file + lineB: { + type: 'object', + geometryId: 'lineB_geom', + name: { [LocalizedString.EN_US]: 'Line B' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-70), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-18), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(61), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Checkpoint 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(105), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can12: { + // Created an invisible can to attach script + ...createCanNode( + 12, + { + x: Distance.centimeters(11), + y: Distance.centimeters(0), + z: Distance.centimeters(91), + }, + false, + false + ), + scriptIds: ['lineFollow'], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc19.ts b/src/simulator/definitions/scenes/jbc19.ts index 79c39b1b..b91a078a 100644 --- a/src/simulator/definitions/scenes/jbc19.ts +++ b/src/simulator/definitions/scenes/jbc19.ts @@ -1,14 +1,47 @@ -import Scene from "../../../state/State/Scene"; -import { RotationwUnits, ReferenceFramewUnits } from "../../../util/math/unitMath"; -import { Distance, Mass } from "../../../util"; +import Scene from '../../../state/State/Scene'; +import { RotationwUnits, ReferenceFramewUnits } from '../../../util/math/unitMath'; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; - +import { Color } from '../../../state/State/Scene/Color'; import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +import Script from "../../../state/State/Scene/Script"; import tr from '@i18n'; const baseScene = createBaseSceneSurfaceA(); +const startBoxIntersects = ` +scene.onBind = nodeId => { + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + console.log(nodeId + "entered start box!"); + const visible = type === 'start'; + scene.setChallengeEventValue(nodeId+'Intersects', visible); + }, 'startBox'); + +}; + +`; + +const uprightCans = ` +// When a can is standing upright on the ream, the upright condition is met. + + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); +scene.addOnRenderListener(() => { + + const upright1 = yAngle('can1') < 5; + const upright2 = yAngle('can2') < 5; + const upright3 = yAngle('can3') < 5; + + scene.setChallengeEventValue('can1Upright', upright1); + scene.setChallengeEventValue('can2Upright', upright2); + scene.setChallengeEventValue('can3Upright', upright3); + + +}); + +`; const REAM_ORIGIN: ReferenceFramewUnits = { position: { x: Distance.centimeters(-10), @@ -23,14 +56,109 @@ const REAM_ORIGIN: ReferenceFramewUnits = { export const JBC_19: Scene = { ...baseScene, - name: tr('JBC 19'), - description: tr('Junior Botball Challenge 19: Mountain Rescue'), + name: { [LocalizedString.EN_US]: 'JBC 19' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 19: Mountain Rescue`, + }, + scripts: { + uprightCans: Script.ecmaScript('Upright Cans', uprightCans), + startBoxIntersects: Script.ecmaScript('Start Box Intersects', startBoxIntersects), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(25), + }, + }, + circle2_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + }, nodes: { ...baseScene.nodes, - 'can1': createCanNode(1, { x: Distance.centimeters(-3), y: Distance.centimeters(6), z: Distance.centimeters(98.6) }), - 'can2': createCanNode(2, { x: Distance.centimeters(-10), y: Distance.centimeters(6), z: Distance.centimeters(91.6) }), - 'can3': createCanNode(3, { x: Distance.centimeters(-17), y: Distance.centimeters(6), z: Distance.centimeters(84.6) }), - 'ream': { + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(3), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can1: { + ...createCanNode(1, { + x: Distance.centimeters(-3), + y: Distance.centimeters(6), + z: Distance.centimeters(98.6), + }), + scriptIds: ['uprightCans', 'startBoxIntersects'], + }, + + can2: { + ...createCanNode(1, { + x: Distance.centimeters(-10), + y: Distance.centimeters(6), + z: Distance.centimeters(91.6), + }), + scriptIds: ['uprightCans', 'startBoxIntersects'], + }, + + can3: { + ...createCanNode(1, { + x: Distance.centimeters(-17), + y: Distance.centimeters(6), + z: Distance.centimeters(84.6), + }), + scriptIds: ['uprightCans', 'startBoxIntersects'], + }, + + ream: { type: 'from-jbc-template', templateId: 'ream', name: tr('Paper Ream'), @@ -38,5 +166,5 @@ export const JBC_19: Scene = { origin: REAM_ORIGIN, visible: true, }, - } -}; \ No newline at end of file + }, +}; diff --git a/src/simulator/definitions/scenes/jbc2.ts b/src/simulator/definitions/scenes/jbc2.ts index ed46c7a4..9cdd5a42 100644 --- a/src/simulator/definitions/scenes/jbc2.ts +++ b/src/simulator/definitions/scenes/jbc2.ts @@ -1,18 +1,304 @@ import Scene from "../../../state/State/Scene"; import LocalizedString from '../../../util/LocalizedString'; - +import Script from "../../../state/State/Scene/Script"; import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; const baseScene = createBaseSceneSurfaceA(); +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can6) is intersecting circle6, the circle glows + +scene.addOnIntersectionListener('can6', (type, otherNodeId) => { + console.log('Can 6 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can6Intersects', visible); + setNodeVisible('circle6', visible); +}, 'circle6'); + +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; +const robotTouches = ` +scene.onBind = nodeId => { + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + console.log('Can 6 touched!', otherNodeId, point); + scene.setChallengeEventValue(nodeId + 'Touched', true); + }, 'robot'); +}; +`; +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const passedSide = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + switch(otherNodeId){ + case 'rightSideCan': + console.log('Robot passed the right side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('rightSide', type === 'start'); + } + break; + case 'topSideCan': + console.log('Robot passed the top side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('topSide', type === 'start'); + } + break; + case 'leftSideCan': + console.log('Robot passed the left side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leftSide', type === 'start'); + } + break; + } +}, ['rightSideCan', 'topSideCan', 'leftSideCan']); + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +// let startTime = Date.now(); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +// const startingOrientationInv = (nodeId) => Quaternion.inverse(RotationwUnits.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + +scene.addOnRenderListener(() => { + // const currTime = Date.now(); + // const timeDiff = currTime - startTime; + const upright6 = yAngle('can6') < 5; + // if(timeDiff > 1000) { + // console.log('can6 angle: ', yAngle('can6')); + // startTime = currTime; + // } + scene.setChallengeEventValue('can6Upright', upright6); + +}); +`; + export const JBC_2: Scene = { ...baseScene, - name: tr('JBC 2'), - description: tr('Junior Botball Challenge 2: Ring Around the Can'), + name: { [LocalizedString.EN_US]: "JBC 2" }, + description: { + [LocalizedString.EN_US]: "Junior Botball Challenge 2: Ring Around the Can", + }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + robotTouches: Script.ecmaScript("Robot Touches", robotTouches), + passedSide: Script.ecmaScript("Passed Side", passedSide), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + + geometry: { + ...baseScene.geometry, + circle6_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + rightSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + + topSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(0.01), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + + leftSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(50), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + }, + nodes: { ...baseScene.nodes, - 'can6': createCanNode(6), - } + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle6: { + type: "object", + geometryId: "circle6_geom", + name: { [LocalizedString.EN_US]: "Circle 6" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + rightSideCan: { + type: "object", + geometryId: "rightSideCan_geom", + name: { [LocalizedString.EN_US]: "Right Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-20), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + topSideCan: { + type: "object", + geometryId: "topSideCan_geom", + name: { [LocalizedString.EN_US]: "Top Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + leftSideCan: { + type: "object", + geometryId: "leftSideCan_geom", + name: { [LocalizedString.EN_US]: "Left Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(52), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can6: { + ...createCanNode(6, { + x: Distance.centimeters(0), + y: Distance.centimeters(0), + z: Distance.centimeters(57), + }), + scriptIds: ["robotTouches"], + }, + }, }; \ No newline at end of file diff --git a/src/simulator/definitions/scenes/jbc20.ts b/src/simulator/definitions/scenes/jbc20.ts index 4c8f57d3..32e1f6ea 100644 --- a/src/simulator/definitions/scenes/jbc20.ts +++ b/src/simulator/definitions/scenes/jbc20.ts @@ -1,19 +1,48 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import { ReferenceFramewUnits } from '../../../util/math/unitMath'; -import { Distance, Mass } from "../../../util"; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; - +import Script from '../../../state/State/Scene/Script'; import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; - import tr from '@i18n'; +const uprightCans = ` +// When a can is standing upright on the ream, the upright condition is met. + + +scene.onBind = nodeId => { + const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); + const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + scene.addOnRenderListener(() => { + + const canUpright2 = yAngle('can2') < 5; + const canUpright9 = yAngle('can9') < 5; + const canUpright10 = yAngle('can10') < 5; + const canUpright12 = yAngle('can12') < 5; + scene.setChallengeEventValue('can2Upright', canUpright2); + scene.setChallengeEventValue('can9Upright', canUpright9); + scene.setChallengeEventValue('can10Upright', canUpright10); + scene.setChallengeEventValue('can12Upright', canUpright12); + + }); + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + const visible = type === 'start'; + scene.setChallengeEventValue(nodeId +'Intersects', visible); + + }, 'ream'); + +}; + +`; + const baseScene = createBaseSceneSurfaceA(); const ROBOT_ORIGIN: ReferenceFramewUnits = { ...baseScene.nodes['robot'].origin, position: { ...baseScene.nodes['robot'].origin.position, - x: Distance.centimeters(18) + x: Distance.centimeters(18), }, }; @@ -27,22 +56,39 @@ const REAM_ORIGIN: ReferenceFramewUnits = { export const JBC_20: Scene = { ...baseScene, - name: tr('JBC 20'), - description: tr('Junior Botball Challenge 20: Rescue the Cans'), + name: { [LocalizedString.EN_US]: 'JBC 20' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 20: Rescue the Cans`, + }, + scripts: { + uprightCans: Script.ecmaScript('Upright Cans', uprightCans), + }, nodes: { ...baseScene.nodes, // The normal starting position of the robot doesn't leave room for the paper ream in the starting box // Start the robot on the left side so that a ream fits on the right side - 'robot': { + robot: { ...baseScene.nodes['robot'], startingOrigin: ROBOT_ORIGIN, - origin: ROBOT_ORIGIN + origin: ROBOT_ORIGIN, + }, + can2: { + ...createCanNode(2), + scriptIds: ['uprightCans'], + }, + can9: { + ...createCanNode(9), + scriptIds: ['uprightCans'], }, - 'can2': createCanNode(2), - 'can9': createCanNode(9), - 'can10': createCanNode(10), - 'can12': createCanNode(12), - 'ream': { + can10: { + ...createCanNode(10), + scriptIds: ['uprightCans'], + }, + can12: { + ...createCanNode(12), + scriptIds: ['uprightCans'], + }, + ream: { type: 'from-jbc-template', templateId: 'ream', name: tr('Paper Ream'), @@ -51,4 +97,4 @@ export const JBC_20: Scene = { visible: true, }, }, -}; \ No newline at end of file +}; diff --git a/src/simulator/definitions/scenes/jbc21.ts b/src/simulator/definitions/scenes/jbc21.ts index c0122b46..d66135e1 100644 --- a/src/simulator/definitions/scenes/jbc21.ts +++ b/src/simulator/definitions/scenes/jbc21.ts @@ -1,18 +1,69 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; - +import { Distance } from '../../../util'; import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from '../../../state/State/Scene/Color'; +import Script from '../../../state/State/Scene/Script'; const baseScene = createBaseSceneSurfaceA(); +const footTallBox = ` + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Bottom of can 9 is at the foot tall mark!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('footTallMark', type === 'end'); + } + +}, 'footTall'); +`; + export const JBC_21: Scene = { ...baseScene, - name: tr('JBC 21'), - description: tr('Junior Botball Challenge 21: Foot Tall'), + name: { [LocalizedString.EN_US]: 'JBC 21' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 21: Foot Tall`, + }, + scripts: { + footTallBox: Script.ecmaScript('Foot Tall Cutoff', footTallBox), + }, + geometry: { + ...baseScene.geometry, + footTall_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + }, nodes: { ...baseScene.nodes, - 'can9': createCanNode(9), - } -}; \ No newline at end of file + footTall: { + type: 'object', + geometryId: 'footTall_geom', + name: { [LocalizedString.EN_US]: 'Foot Tall Cutoff' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(0), // circle 6 + y: Distance.inches(11), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can9: { + ...createCanNode(9), + scriptIds: ["footTallBox"], + + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc22.ts b/src/simulator/definitions/scenes/jbc22.ts index d9fe2af5..4fc5252a 100644 --- a/src/simulator/definitions/scenes/jbc22.ts +++ b/src/simulator/definitions/scenes/jbc22.ts @@ -1,19 +1,239 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; - +import { Distance } from '../../../util'; import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from '../../../state/State/Scene/Color'; +import Script from '../../../state/State/Scene/Script'; const baseScene = createBaseSceneSurfaceA(); +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const canStacked = ` + +scene.addOnIntersectionListener('can5Bottom', (type, otherNodeId) => { + if(otherNodeId == 'can7Top'){ + console.log("Can5 stacked ontop of Can7!"); + scene.setChallengeEventValue('canStacked', true); + } + else if (otherNodeId == 'mainSurface'){ + scene.setChallengeEventValue('canStacked', false); + } + +}, ['can7Top', 'mainSurface']); + +scene.addOnIntersectionListener('can7Bottom', (type, otherNodeId) => { + + if(otherNodeId == 'can5Top'){ + console.log("Can7 stacked ontop of Can5!"); + scene.setChallengeEventValue('canStacked', true); + } + else if (otherNodeId == 'mainSurface'){ + scene.setChallengeEventValue('canStacked', false); + } + +}, ['can5Top', 'mainSurface']); + + +`; + +const robotTouchesCan = ` + +scene.onBind = nodeId => { + + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + if(nodeId == 'can5' || nodeId == 'can7'){ + scene.setChallengeEventValue('robotTouchCan', true); + } + + }, ['robot']); + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + scene.setChallengeEventValue('robotTouchCan', false); + }, ['mainSurface']); +}; +`; + export const JBC_22: Scene = { ...baseScene, - name: tr('JBC 22'), - description: tr('Junior Botball Challenge 22: Stackerz'), + name: { [LocalizedString.EN_US]: 'JBC 22' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 22: Stackerz`, + }, + scripts: { + leftStartBox: Script.ecmaScript('Robot Left Start', leftStartBox), + canStacked: Script.ecmaScript('Cans Stacked', canStacked), + robotTouchesCan: Script.ecmaScript('Robot Touches Can', robotTouchesCan), + }, + geometry: { + ...baseScene.geometry, + + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(1.77), + y: Distance.centimeters(0.1), + z: Distance.centimeters(30), + }, + }, + canEnd_geom: { + type: 'cylinder', + + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + }, + nodes: { ...baseScene.nodes, - 'can5': createCanNode(5), - 'can7': createCanNode(7), - } -}; \ No newline at end of file + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can5: { ...createCanNode(5), scriptIds: ['canStacked', 'robotTouchesCan'] }, + can7: { ...createCanNode(7), scriptIds: ['canStacked', 'robotTouchesCan'] }, + can5Bottom: { + parentId: 'can5', + type: 'object', + geometryId: 'canEnd_geom', + name: { [LocalizedString.EN_US]: 'Bottom of can5' }, + + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-5.8), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can7Top: { + parentId: 'can7', + type: 'object', + geometryId: 'canEnd_geom', + name: { [LocalizedString.EN_US]: 'Top of can7' }, + + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(5.75), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can7Bottom: { + parentId: 'can7', + type: 'object', + geometryId: 'canEnd_geom', + name: { [LocalizedString.EN_US]: 'Bottom of can7' }, + + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-5.8), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can5Top: { + parentId: 'can5', + type: 'object', + geometryId: 'canEnd_geom', + name: { [LocalizedString.EN_US]: 'Top of can5' }, + + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(5.75), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc2b.ts b/src/simulator/definitions/scenes/jbc2b.ts index c3a2ab10..c00ce0b1 100644 --- a/src/simulator/definitions/scenes/jbc2b.ts +++ b/src/simulator/definitions/scenes/jbc2b.ts @@ -1,20 +1,368 @@ import Scene from "../../../state/State/Scene"; import LocalizedString from '../../../util/LocalizedString'; - import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; +import Script from "../../../state/State/Scene/Script"; const baseScene = createBaseSceneSurfaceA(); +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can10) is intersecting circle10, the circle glows + +scene.addOnIntersectionListener('can10', (type, otherNodeId) => { + console.log('Can 10 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can10Intersects', visible); + setNodeVisible('circle10', visible); +}, 'circle10'); + +// When the can (can11) is intersecting circle11, the circle glows + +scene.addOnIntersectionListener('can11', (type, otherNodeId) => { + console.log('Can 11 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can11Intersects', visible); + setNodeVisible('circle11', visible); +}, 'circle11'); + + +// When the can (can12) is intersecting circle12, the circle glows + +scene.addOnIntersectionListener('can12', (type, otherNodeId) => { + console.log('Can 12 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can12Intersects', visible); + setNodeVisible('circle12', visible); +}, 'circle12'); +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; +const robotTouches = ` +scene.onBind = nodeId => { + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + console.log(nodeId + 'touched!', otherNodeId, point); + scene.setChallengeEventValue(nodeId + 'Touched', true); + }, 'robot'); +}; +`; +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const passedSide = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + switch(otherNodeId){ + case 'rightSideCan': + console.log('Robot passed the right side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('rightSide', type === 'start'); + } + break; + case 'topSideCan': + console.log('Robot passed the top side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('topSide', type === 'start'); + } + break; + case 'leftSideCan': + console.log('Robot passed the left side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leftSide', type === 'start'); + } + break; + } +}, ['rightSideCan', 'topSideCan', 'leftSideCan']); + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +// let startTime = Date.now(); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +// const startingOrientationInv = (nodeId) => Quaternion.inverse(RotationwUnits.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + +scene.addOnRenderListener(() => { + // const currTime = Date.now(); + // const timeDiff = currTime - startTime; + const upright10 = yAngle('can10') < 5; + const upright11 = yAngle('can11') < 5; + const upright12 = yAngle('can12') < 5; + // if(timeDiff > 1000) { + // console.log('can6 angle: ', yAngle('can6')); + // startTime = currTime; + // } + scene.setChallengeEventValue('can10Upright', upright10); + scene.setChallengeEventValue('can11Upright', upright11); + scene.setChallengeEventValue('can12Upright', upright12); +}); +`; + export const JBC_2B: Scene = { ...baseScene, - name: tr('JBC 2B'), - description: tr('Junior Botball Challenge 2B: Ring Around the Can, Sr.'), + name: { [LocalizedString.EN_US]: 'JBC 2B' }, + description: { [LocalizedString.EN_US]: 'Junior Botball Challenge 2B: Ring Around the Can, Sr.' }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + robotTouches: Script.ecmaScript("Robot Touches", robotTouches), + passedSide: Script.ecmaScript("Passed Side", passedSide), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + geometry: { + ...baseScene.geometry, + circle10_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle11_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle12_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + rightSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + + topSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(0.01), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + + leftSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + }, + nodes: { ...baseScene.nodes, - 'can10': createCanNode(10), - 'can11': createCanNode(11), - 'can12': createCanNode(12), + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle10: { + type: "object", + geometryId: "circle10_geom", + name: { [LocalizedString.EN_US]: "Circle 10" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(19.3), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle11: { + type: "object", + geometryId: "circle11_geom", + name: { [LocalizedString.EN_US]: "Circle 11" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(106.6), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle12: { + type: "object", + geometryId: "circle12_geom", + name: { [LocalizedString.EN_US]: "Circle 12" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-19.2), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + rightSideCan: { + type: "object", + geometryId: "rightSideCan_geom", + name: { [LocalizedString.EN_US]: "Right Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-50), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + topSideCan: { + type: "object", + geometryId: "topSideCan_geom", + name: { [LocalizedString.EN_US]: "Top Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + leftSideCan: { + type: "object", + geometryId: "leftSideCan_geom", + name: { [LocalizedString.EN_US]: "Left Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(50), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(96.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + ...baseScene.nodes, + 'can10': { ...createCanNode(10), scriptIds: ["robotTouches"] }, + 'can11': { ...createCanNode(11), scriptIds: ["robotTouches"] }, + 'can12': { ...createCanNode(12), scriptIds: ["robotTouches"] }, } }; \ No newline at end of file diff --git a/src/simulator/definitions/scenes/jbc2c.ts b/src/simulator/definitions/scenes/jbc2c.ts index b435250f..e7d45f3b 100644 --- a/src/simulator/definitions/scenes/jbc2c.ts +++ b/src/simulator/definitions/scenes/jbc2c.ts @@ -1,18 +1,310 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; -import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); + +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can6) is intersecting circle6, the circle glows + +scene.addOnIntersectionListener('can6', (type, otherNodeId) => { + console.log('Can 6 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can6Intersects', visible); + setNodeVisible('circle6', visible); +}, 'circle6'); + +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; +const robotTouches = ` +scene.onBind = nodeId => { + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + console.log('Can 6 touched!', otherNodeId, point); + scene.setChallengeEventValue(nodeId + 'Touched', true); + }, 'robot'); +}; +`; +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const passedSide = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + switch(otherNodeId){ + case 'rightSideCan': + console.log('Robot passed the right side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('rightSide', type === 'start'); + } + break; + case 'topSideCan': + console.log('Robot passed the top side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('topSide', type === 'start'); + } + break; + case 'leftSideCan': + console.log('Robot passed the left side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leftSide', type === 'start'); + } + break; + } +}, ['rightSideCan', 'topSideCan', 'leftSideCan']); + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + +scene.addOnRenderListener(() => { + + const upright6 = yAngle('can6') < 5; + scene.setChallengeEventValue('can6Upright', upright6); + +}); +`; + +const goingBackwards = ` +scene.addOnRenderListener(() => { + + if(scene.nodes['robot'].state.motors[0].direction === 1 && scene.nodes['robot'].state.motors[3].direction === 1){ + scene.setChallengeEventValue('driveBackwards', false); + } + else { + scene.setChallengeEventValue('driveBackwards', true); + } +});`; -import tr from '@i18n'; -const baseScene = createBaseSceneSurfaceA(); export const JBC_2C: Scene = { ...baseScene, - name: tr('JBC 2C'), - description: tr('Junior Botball Challenge 2C: Back It Up'), + name: { [LocalizedString.EN_US]: "JBC 2C" }, + description: { + [LocalizedString.EN_US]: "Junior Botball Challenge 2C: Back It Up", + }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + goingBackwards: Script.ecmaScript("Going Backwards", goingBackwards), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + robotTouches: Script.ecmaScript("Robot Touches", robotTouches), + passedSide: Script.ecmaScript("Passed Side", passedSide), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + + geometry: { + ...baseScene.geometry, + circle6_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + rightSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + + topSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(0.01), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + + leftSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(50), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + }, + nodes: { ...baseScene.nodes, - 'can6': createCanNode(6), - } -}; \ No newline at end of file + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle6: { + type: "object", + geometryId: "circle6_geom", + name: { [LocalizedString.EN_US]: "Circle 6" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + rightSideCan: { + type: "object", + geometryId: "rightSideCan_geom", + name: { [LocalizedString.EN_US]: "Right Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-20), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + topSideCan: { + type: "object", + geometryId: "topSideCan_geom", + name: { [LocalizedString.EN_US]: "Top Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + leftSideCan: { + type: "object", + geometryId: "leftSideCan_geom", + name: { [LocalizedString.EN_US]: "Left Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(52), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can6: { + ...createCanNode(6, { + x: Distance.centimeters(0), + y: Distance.centimeters(0), + z: Distance.centimeters(57), + }), + scriptIds: ["robotTouches"], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc2d.ts b/src/simulator/definitions/scenes/jbc2d.ts index fa8e2aa8..6bbeeffe 100644 --- a/src/simulator/definitions/scenes/jbc2d.ts +++ b/src/simulator/definitions/scenes/jbc2d.ts @@ -1,18 +1,314 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; -import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); + +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can6) is intersecting circle6, the circle glows + +scene.addOnIntersectionListener('can6', (type, otherNodeId) => { + console.log('Can 6 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can6Intersects', visible); + setNodeVisible('circle6', visible); +}, 'circle6'); + +`; + +const robotTouches = ` +scene.onBind = nodeId => { + scene.addOnCollisionListener(nodeId, (otherNodeId, point)=> { + console.log('Can 6 touched!', otherNodeId, point); + scene.setChallengeEventValue(nodeId + 'Touched', true); + }, 'robot'); +}; +`; +const enterStartBox = ` + +scene.onBind = nodeId => { + let count = 0; + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + if(scene.programStatus === 'running' && count == 0 && type === 'start'){ + scene.setChallengeEventValue('returnStartBox1', type === 'start'); + console.log('Robot returned start box the 1st time!', type, otherNodeId); + count = 1; + } + else if(scene.programStatus === 'running' && count == 1 && type === 'start'){ + scene.setChallengeEventValue('returnStartBox2', type === 'start'); + console.log('Robot returned start box the 2nd time!', type, otherNodeId); + count = 0; + } + }, 'startBox'); +}; +`; + +const passedSide = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + switch(otherNodeId){ + case 'rightSideCan': + console.log('Robot passed the right side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('rightSide', type === 'start'); + } + break; + case 'topSideCan': + console.log('Robot passed the top side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('topSide', type === 'start'); + } + break; + case 'leftSideCan': + console.log('Robot passed the left side of the can!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leftSide', type === 'start'); + } + break; + } +}, ['rightSideCan', 'topSideCan', 'leftSideCan']); + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + +scene.addOnRenderListener(() => { + + const upright6 = yAngle('can6') < 5; + scene.setChallengeEventValue('can6Upright', upright6); + +}); +`; + +const goingBackwards = ` + +scene.addOnRenderListener(() => { + + //robot going forwards + if(scene.nodes['robot'].state.motors[0].direction == 1 || scene.nodes['robot'].state.motors[3].direction == 1){ + scene.setChallengeEventValue('driveForwards', true); + } + + //robot going backwards + else if (scene.nodes['robot'].state.motors[0].direction === 2 && scene.nodes['robot'].state.motors[3].direction ===2){ + scene.setChallengeEventValue('driveBackwards', true); + } + +}); + +`; -import tr from '@i18n'; -const baseScene = createBaseSceneSurfaceA(); export const JBC_2D: Scene = { ...baseScene, - name: tr('JBC 2D'), - description: tr('Junior Botball Challenge 2D: Ring Around the Can and Back It Up'), + name: { [LocalizedString.EN_US]: 'JBC 2D' }, + description: { [LocalizedString.EN_US]: 'Junior Botball Challenge 2D: Ring Around the Can and Back It Up' }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + goingBackwards: Script.ecmaScript("Going Backwards", goingBackwards), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + robotTouches: Script.ecmaScript("Robot Touches", robotTouches), + passedSide: Script.ecmaScript("Passed Side", passedSide), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + + geometry: { + ...baseScene.geometry, + circle6_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + rightSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + + topSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(0.01), + y: Distance.centimeters(0.1), + z: Distance.meters(1.77), + }, + }, + + leftSideCan_geom: { + type: "box", + size: { + x: Distance.centimeters(50), + y: Distance.centimeters(0.1), + z: Distance.meters(0.05), + }, + }, + }, + nodes: { ...baseScene.nodes, - 'can6': createCanNode(6), - } + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle6: { + type: "object", + geometryId: "circle6_geom", + name: { [LocalizedString.EN_US]: "Circle 6" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + rightSideCan: { + type: "object", + geometryId: "rightSideCan_geom", + name: { [LocalizedString.EN_US]: "Right Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-20), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + topSideCan: { + type: "object", + geometryId: "topSideCan_geom", + name: { [LocalizedString.EN_US]: "Top Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + leftSideCan: { + type: "object", + geometryId: "leftSideCan_geom", + name: { [LocalizedString.EN_US]: "Left Side Can" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(52), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + can6: { + ...createCanNode(6, { + x: Distance.centimeters(0), + y: Distance.centimeters(0), + z: Distance.centimeters(57), + }), + scriptIds: ["robotTouches", "enterStartBox", "goingBackwards"], + }, + }, }; \ No newline at end of file diff --git a/src/simulator/definitions/scenes/jbc3.ts b/src/simulator/definitions/scenes/jbc3.ts index be955d4e..08608725 100644 --- a/src/simulator/definitions/scenes/jbc3.ts +++ b/src/simulator/definitions/scenes/jbc3.ts @@ -1,14 +1,701 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; +import Script from '../../../state/State/Scene/Script'; +import { Distance, Angle } from '../../../util'; +import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +import { RotationwUnits } from '../../../util/math/unitMath'; +import { Color } from '../../../state/State/Scene/Color'; +import { RawVector2 } from '../../../util/math/math'; -import { createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const garageIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +let chosenGarage = []; +let declaredGarage = []; +let clicked = true; + +//state == 0 (reset), state == 1 (1 garage parked), state == 2 (finished) +let state = 0; + +let selected = 0; + +scene.onBind = nodeId => { + + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + //Value resets + if (state >= 2){ + state = 0; + } + if(selected >= 2){ + selected = 0; + } + + //Entering StartBox Events + if(otherNodeId == 'startBox' && type == 'start'){ + + //Reset Challenge Sequence + if(state == 0 && chosenGarage.length > 0){ + for (let i = 0; i < chosenGarage.length; i++){ + chosenGarage.pop(); + } + for (let i = 0; i < declaredGarage.length; i++){ + declaredGarage.pop(); + } + + clicked = true; + + } + + //Return to startbox after first garage park + else if(state == 1 && chosenGarage.length > 0){ + scene.setChallengeEventValue('returnStartBox', true); + setNodeVisible(chosenGarage[0], false); + clicked = true; + + + if(declaredGarage.includes('greenBox')){ + setNodeVisible('yellowBox', true); + setNodeVisible('blueBox', true); + + } + else if (declaredGarage.includes('yellowBox')){ + setNodeVisible('greenBox', true); + setNodeVisible('blueBox', true); + + } + else if (declaredGarage.includes('blueBox')){ + setNodeVisible('greenBox', true); + setNodeVisible('yellowBox', true); + + } + chosenGarage.pop(); + declaredGarage.pop(); + } + } + //Entering Garage Events + if(type == 'start'){ + + if(otherNodeId == 'n1' && declaredGarage.includes('greenBox')){ + setNodeVisible('greenGarage', true); + state++; + selected++; + } + else if(otherNodeId == 'n2' && declaredGarage.includes('yellowBox')) { + setNodeVisible('yellowGarage', true); + state++; + selected++; + } + else if(otherNodeId == 'n3' && declaredGarage.includes('blueBox')) { + setNodeVisible('blueGarage', true); + state++; + selected++; + } + } + + + if(selected == 1){ + scene.setChallengeEventValue('singleGarageRun1', true); + } + else if (selected == 2){ + scene.setChallengeEventValue('singleGarageRun2', true); + } + + }, ['startBox', 'greenBox', 'yellowBox', 'blueBox','n1','n2','n3']); + + + //User declares garage + scene.addOnClickListener(['greenBox','yellowBox','blueBox'], id => { + + clicked = !clicked; + setNodeVisible('greenBox', clicked); + setNodeVisible('yellowBox', clicked); + setNodeVisible('blueBox', clicked); + if(id == 'greenBox'){ + chosenGarage.push('greenGarage'); + declaredGarage.push('greenBox'); + } + else if(id == 'yellowBox'){ + chosenGarage.push('yellowGarage'); + declaredGarage.push('yellowBox'); + } + else if(id == 'blueBox'){ + chosenGarage.push('blueGarage'); + declaredGarage.push('blueBox'); + } + }); -const baseScene = createBaseSceneSurfaceA(); + + + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + if(declaredGarage.includes('greenBox') && + (otherNodeId == 'g1' || otherNodeId == 'g2' || otherNodeId == 'g3')){ + state = 0; + selected = 0; + scene.setChallengeEventValue('touchGarageLines', true); + } + else if(declaredGarage.includes('blueBox') && + (otherNodeId == 'b1' || otherNodeId == 'b2' || otherNodeId == 'b3')){ + state = 0; + selected = 0; + scene.setChallengeEventValue('touchGarageLines', true); + } + else if(declaredGarage.includes('yellowBox') && + (otherNodeId == 'y1' || otherNodeId == 'y2' || otherNodeId == 'y3')){ + state = 0; + selected = 0; + scene.setChallengeEventValue('touchGarageLines', true); + } + }, ['g1', 'g2','g3', 'b1','b2','b3', 'y1', 'y2', 'y3']); + + + + +} +`; export const JBC_3: Scene = { ...baseScene, - name: tr('JBC 3'), - description: tr('Junior Botball Challenge 3: Precision Parking'), -}; \ No newline at end of file + name: { [LocalizedString.EN_US]: 'JBC 3' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 3: Precision Parking', + }, + scripts: { + garageIntersects: Script.ecmaScript('Garage Intersects', garageIntersects), + // clicked: Script.ecmaScript('Garage Intersects', clicked), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + n_geom: { + type: 'cylinder', + radius: Distance.centimeters(0.01), + height: Distance.centimeters(0.1), + }, + designatorBox_geom: { + type: 'box', + size: { + x: Distance.centimeters(10), + y: Distance.centimeters(1), + z: Distance.centimeters(10), + }, + }, + greenGarage_geom: { + type: 'box', + size: { + x: Distance.centimeters(18), + y: Distance.centimeters(0.1), + z: Distance.centimeters(18), + }, + }, + blueGarage_geom: { + type: 'box', + size: { + x: Distance.centimeters(18), + y: Distance.centimeters(0.1), + z: Distance.centimeters(18), + }, + }, + yellowGarage_geom: { + type: 'box', + size: { + x: Distance.centimeters(16), + y: Distance.centimeters(0.1), + z: Distance.centimeters(18), + }, + }, + }, + nodes: { + ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + greenBox: { + type: 'object', + geometryId: 'designatorBox_geom', + name: { [LocalizedString.EN_US]: 'Green Garage Designator Box' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6), + z: Distance.centimeters(53), + }, + orientation: { + + type: 'euler', + x: Angle.degrees(0), + y: Angle.degrees(-90), + z: Angle.degrees(0), + }, + }, + material: { + type: 'basic', + color: { + type: 'texture', + uri: '/static/Click Here.png', + }, + }, + faceUvs: [ + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.create(0, 1), RawVector2.create(1, 0), // TOP + RawVector2.ZERO, RawVector2.ZERO, + ], + }, + + yellowBox: { + type: 'object', + geometryId: 'designatorBox_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage Designator Box' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(18.5), + y: Distance.centimeters(-6), + z: Distance.centimeters(78.9), + }, + orientation: { + + type: 'euler', + x: Angle.degrees(0), + y: Angle.degrees(-90), + z: Angle.degrees(0), + }, + }, + material: { + type: 'basic', + color: { + type: 'texture', + uri: '/static/Click Here.png', + }, + }, + faceUvs: [ + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.create(0, 1), RawVector2.create(1, 0), // TOP + RawVector2.ZERO, RawVector2.ZERO, + ], + }, + + blueBox: { + type: 'object', + geometryId: 'designatorBox_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage Designator Box' }, + visible: true, + origin: { + position: { + x: Distance.centimeters(-12), + y: Distance.centimeters(-6), + z: Distance.centimeters(94), + }, + orientation: { + + type: 'euler', + x: Angle.degrees(0), + y: Angle.degrees(-135), + z: Angle.degrees(0), + }, + }, + material: { + type: 'basic', + color: { + type: 'texture', + uri: '/static/Click Here.png', + }, + }, + faceUvs: [ + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.ZERO, RawVector2.ZERO, + RawVector2.create(0, 1), RawVector2.create(1, 0), // TOP + RawVector2.ZERO, RawVector2.ZERO, + ], + }, + + greenGarage: { + type: 'object', + geometryId: 'greenGarage_geom', + name: { [LocalizedString.EN_US]: 'Green Garage' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Green Garage node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(58), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18.5), + y: Distance.centimeters(-6), + z: Distance.centimeters(73.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-14), + y: Distance.centimeters(-6), + z: Distance.centimeters(96), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + g1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Green Garage Right Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-11.5), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + g2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Green Garage Left Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(12), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + g3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Green Garage Top Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + + blueGarage: { + type: 'object', + geometryId: 'blueGarage_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-12.5), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(94.5), + }, + orientation: RotationwUnits.AxisAngle.fromRaw({ + axis: { x: 0, y: 1, z: 0 }, + angle: 115.5, + }), + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + b1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage Right Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-19.2), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(86.4), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + b2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage Left Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-5), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(102.6), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + b3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Blue Garage Top Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-19.2), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(102), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + yellowGarage: { + type: 'object', + geometryId: 'yellowGarage_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18.8), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(78), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + y1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage Right Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(29.3), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(77.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + y2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage Left Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(9.3), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(77.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + y3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Yellow Garage Top Boundary node' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(18.3), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(68.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can12: { + // Created an invisible can to attach script + ...createCanNode( + 12, + { + x: Distance.centimeters(11), + y: Distance.centimeters(0), + z: Distance.centimeters(91), + }, + false, + false + ), + scriptIds: ['garageIntersects'], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc4.ts b/src/simulator/definitions/scenes/jbc4.ts index a147792d..766ad535 100644 --- a/src/simulator/definitions/scenes/jbc4.ts +++ b/src/simulator/definitions/scenes/jbc4.ts @@ -1,19 +1,334 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; - -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can4) is intersecting circle4, the circle glows + +scene.addOnIntersectionListener('can4', (type, otherNodeId) => { + console.log('Can 4 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can4Intersects', visible); + setNodeVisible('circle4', visible); +}, 'circle4'); + +// When the can (can9) is intersecting circle9, the circle glows + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Can 9 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can9Intersects', visible); + setNodeVisible('circle9', visible); +}, 'circle9'); + +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const passedSide = ` + +let count = 0; +let position = 0; +scene.onBind = nodeId => { + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + if(otherNodeId == "startBox"){ + count = 0; + position = 0; + } + + if(type === "start"){ + position++; + console.log(count + ":" + otherNodeId + ":" + type + ":Position:" +position ); + } + + //Sets values for second crossing in the middle + if(count == 2 && (otherNodeId == "n1")){ + count++; + position = 3; + console.log(count + ":" + otherNodeId + ":" + type); + } + if(type==="start" && (otherNodeId == "n" +position)){ + count++; + console.log(count + ":" + otherNodeId + ":" + type); + + } + + //Passed three checkmarks and recently passed the middle checkmark + if(count == 3 && otherNodeId == "n1"){ + scene.setChallengeEventValue('figureEight', true); + } + else{ + scene.setChallengeEventValue('figureEight', false); + } + + if(position == 0 ){ + count = 0; + } + + + }, ['startBox', 'n1', 'n2']); +}; + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + +scene.addOnRenderListener(() => { + + const upright4 = yAngle('can4') < 5; + const upright9 = yAngle('can9') < 5; + + scene.setChallengeEventValue('can4Upright', upright4); + scene.setChallengeEventValue('can9Upright', upright9); +}); +`; export const JBC_4: Scene = { ...baseScene, - name: tr('JBC 4'), - description: tr('Junior Botball Challenge 4: Figure Eight'), + name: { [LocalizedString.EN_US]: "JBC 4" }, + description: { + [LocalizedString.EN_US]: "Junior Botball Challenge 4: Figure Eight", + }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + passedSide: Script.ecmaScript("Passed Side", passedSide), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + + geometry: { + ...baseScene.geometry, + circle4_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle9_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + + leftCan4_geom: { + type: "box", + size: { + x: Distance.centimeters(150), + y: Distance.centimeters(1), + z: Distance.centimeters(5), + }, + }, + middle_geom: { + type: "box", + size: { + x: Distance.centimeters(-1), + y: Distance.centimeters(-8), + z: Distance.centimeters(30), + }, + }, + rightCan9_geom: { + type: "box", + size: { + x: Distance.centimeters(150), + y: Distance.centimeters(1), + z: Distance.centimeters(5), + }, + }, + topCan9_geom: { + type: "box", + size: { + x: Distance.centimeters(-1), + y: Distance.centimeters(-8), + z: Distance.centimeters(50), + }, + }, + rightCan4_geom: { + type: "box", + size: { + x: Distance.centimeters(150), + y: Distance.centimeters(1), + z: Distance.centimeters(5), + }, + }, + }, + nodes: { ...baseScene.nodes, - 'can4': createCanNode(4), - 'can9': createCanNode(9), - } -}; \ No newline at end of file + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + circle4: { + type: "object", + geometryId: "circle4_geom", + name: { [LocalizedString.EN_US]: "Circle 4" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(42.7), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle9: { + type: "object", + geometryId: "circle9_geom", + name: { [LocalizedString.EN_US]: "Circle 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n1: { + type: "object", + geometryId: "middle_geom", + name: { [LocalizedString.EN_US]: "Between cans 4 and 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(70), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + n2: { + type: "object", + geometryId: "topCan9_geom", + name: { [LocalizedString.EN_US]: "Top side of can 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(115), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + + can4: { ...createCanNode(4) }, + can9: { ...createCanNode(9), scriptIds: ["passedSide"] }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc4b.ts b/src/simulator/definitions/scenes/jbc4b.ts index 48304ae2..414e7612 100644 --- a/src/simulator/definitions/scenes/jbc4b.ts +++ b/src/simulator/definitions/scenes/jbc4b.ts @@ -1,20 +1,450 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const circleIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); -const baseScene = createBaseSceneSurfaceA(); +// When the can (can5) is intersecting circle4, the circle glows + +scene.addOnIntersectionListener('can5', (type, otherNodeId) => { + console.log('Can 5 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can5Intersects', visible); + setNodeVisible('circle5', visible); +}, 'circle5'); +// When the can (can8) is intersecting circle4, the circle glows + +scene.addOnIntersectionListener('can8', (type, otherNodeId) => { + console.log('Can 8 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can8Intersects', visible); + setNodeVisible('circle8', visible); +}, 'circle8'); + +// When the can (can9) is intersecting circle9, the circle glows + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Can 9 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can9Intersects', visible); + setNodeVisible('circle9', visible); +}, 'circle9'); + +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const enterStartBox = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const passedSide = ` + +let count = 0; +let position = 0; +scene.onBind = nodeId => { + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + + if(otherNodeId == "startBox"){ + count = 0; + position = 0; + } + + if(type === "start"){ + position++; + console.log(count + ":" + otherNodeId + ":" + type + ":Position:" +position ); + } + + + if(type==="start" && (otherNodeId == "n" +position)){ + count++; + console.log(count + ":" + otherNodeId + ":" + type); + + } + + if(count == 2 && otherNodeId == "n2"){ + scene.setChallengeEventValue('clockwise8', true); + } + else if (count == 4 && otherNodeId == "n4"){ + scene.setChallengeEventValue('counterClockwise5', true); + } + else if(count == 6 && otherNodeId == "n6"){ + scene.setChallengeEventValue('counterClockwise9', true); + } + if(position == 0 ){ + count = 0; + } + + + }, ['startBox', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6']); +}; + +`; +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + +scene.addOnRenderListener(() => { + + const upright5 = yAngle('can5') < 5; + const upright8 = yAngle('can8') < 5; + const upright9 = yAngle('can9') < 5; + + scene.setChallengeEventValue('can5Upright', upright5); + scene.setChallengeEventValue('can8Upright', upright8); + scene.setChallengeEventValue('can9Upright', upright9); +}); +`; export const JBC_4B: Scene = { ...baseScene, - name: tr('JBC 4B'), - description: tr('Junior Botball Challenge 4B: Barrel Racing'), + name: { [LocalizedString.EN_US]: 'JBC 4B' }, + description: { [LocalizedString.EN_US]: 'Junior Botball Challenge 4B: Barrel Racing' }, + scripts: { + circleIntersects: Script.ecmaScript("Circle Intersects", circleIntersects), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + passedSide: Script.ecmaScript("Passed Side", passedSide), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + geometry: { + ...baseScene.geometry, + circle5_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle8_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle9_geom: { + type: "cylinder", + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + rightCan8_geom: { + type: "box", + size: { + x: Distance.centimeters(80), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0.1), + }, + }, + leftCan8_geom: { + type: "box", + size: { + x: Distance.centimeters(5), + y: Distance.centimeters(0.1), + z: Distance.centimeters(20), + }, + }, + topCan5_geom: { + type: "box", + size: { + x: Distance.centimeters(30), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0.1), + }, + }, + leftCan5_geom: { + type: "box", + size: { + x: Distance.centimeters(80), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0.1), + }, + }, + topCan9_geom: { + type: "box", + size: { + x: Distance.centimeters(0.1), + y: Distance.centimeters(0.1), + z: Distance.centimeters(1), + }, + }, + leftCan9_geom: { + type: "box", + size: { + x: Distance.centimeters(0.1), + y: Distance.centimeters(0.1), + z: Distance.centimeters(1), + }, + }, + }, + nodes: { + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle5: { + type: "object", + geometryId: "circle5_geom", + name: { [LocalizedString.EN_US]: "Circle 5" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(14.3), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle8: { + type: "object", + geometryId: "circle8_geom", + name: { [LocalizedString.EN_US]: "Circle 8" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-26), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65.5), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle9: { + type: "object", + geometryId: "circle9_geom", + name: { [LocalizedString.EN_US]: "Circle 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(85.4), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n2: { + type: "object", + geometryId: "leftCan8_geom", + name: { [LocalizedString.EN_US]: "Can 8" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-37), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(43), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n1: { + type: "object", + geometryId: "rightCan8_geom", + name: { [LocalizedString.EN_US]: "Can 8" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-80), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65.5), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n3: { + type: "object", + geometryId: "topCan5_geom", + name: { [LocalizedString.EN_US]: "Can 5" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(75), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(67.7), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n4: { + type: "object", + geometryId: "leftCan5_geom", + name: { [LocalizedString.EN_US]: "Can 5" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(75), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + n5: { + type: "object", + geometryId: "topCan9_geom", + name: { [LocalizedString.EN_US]: "Can 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-5), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(110), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + + + }, + n6: { + type: "object", + geometryId: "leftCan9_geom", + name: { [LocalizedString.EN_US]: "Can 9" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(8), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(110), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + + + }, + ...baseScene.nodes, - 'can5': createCanNode(5), - 'can8': createCanNode(8), - 'can9': createCanNode(9), + can5: { ...createCanNode(5), scriptIds: ["passedSide"] }, + can8: createCanNode(8), + can9: createCanNode(9), } }; \ No newline at end of file diff --git a/src/simulator/definitions/scenes/jbc5.ts b/src/simulator/definitions/scenes/jbc5.ts index 58307b36..662496da 100644 --- a/src/simulator/definitions/scenes/jbc5.ts +++ b/src/simulator/definitions/scenes/jbc5.ts @@ -1,13 +1,126 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; +import LocalizedString from '../../../util/LocalizedString'; +import Script from '../../../state/State/Scene/Script'; +import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import { Distance } from '../../../util'; -import { createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const leftStartBox = ` -const baseScene = createBaseSceneSurfaceA(); +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const goingBackwards = ` +let degrees = []; +scene.addOnRenderListener(() => { + + const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); + const xAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.X, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.X)); + let angle = xAngle('robot'); + console.log(angle); + if(angle >= 179 && angle <= 180){ + degrees[0] = 0; + degrees[1] = 180; + + } + if(angle <= 1 && (degrees[1] == 180)&& ((scene.nodes['robot'].state.motors[0].pwm > scene.nodes['robot'].state.motors[3].pwm) || scene.nodes['robot'].state.motors[3].direction === 2)){ + scene.setChallengeEventValue('counterClockwise360', true); + degrees.pop(); + degrees.pop(); + } + else if (angle <=1 && (degrees[1] == 180) && (scene.nodes['robot'].state.motors[3].pwm > scene.nodes['robot'].state.motors[0].pwm) && scene.nodes['robot'].state.motors[3].direction != 2 ) + { + scene.setChallengeEventValue('clockwise360', true); + degrees.pop(); + degrees.pop(); + } + console.log("0 PDM: " + scene.nodes['robot'].state.motors[0].pwm); + console.log("3 PDM: " + scene.nodes['robot'].state.motors[3].pwm); + console.log("0 direction: " + scene.nodes['robot'].state.motors[0].direction); + console.log("3 direction: " + scene.nodes['robot'].state.motors[3].direction); + console.log(degrees) ; +}); + +`; export const JBC_5: Scene = { ...baseScene, - name: tr('JBC 5'), - description: tr('Junior Botball Challenge 5: Dance Party') -}; \ No newline at end of file + name: { [LocalizedString.EN_US]: 'JBC 5' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 5: Dance Party', + }, + scripts: { + goingBackwards: Script.ecmaScript('Going Backwards', goingBackwards), + leftStartBox: Script.ecmaScript('Robot Reentered Start', leftStartBox), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + }, + nodes: { + ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc6.ts b/src/simulator/definitions/scenes/jbc6.ts index 472ce697..3528862f 100644 --- a/src/simulator/definitions/scenes/jbc6.ts +++ b/src/simulator/definitions/scenes/jbc6.ts @@ -1,20 +1,207 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import { createBaseSceneSurfaceA, createCanNode } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; +import Script from "../../../state/State/Scene/Script"; -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const garageIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); + +// When the can (can2) is intersecting the green garage, the garage glows + +scene.addOnIntersectionListener('can2', (type, otherNodeId) => { + console.log('Can 2 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can2Intersects', visible); + setNodeVisible('greenGarage', visible); +}, 'greenGarage'); + +// When the can (can9) is intersecting the blue garage, the garage glows + +scene.addOnIntersectionListener('can9', (type, otherNodeId) => { + console.log('Can 9 placed!', type, otherNodeId); + const visible = type === 'start'; + scene.setChallengeEventValue('can9Intersects', visible); + setNodeVisible('circle9', visible); +}, 'circle9'); + + +// // When the can (can10) is intersecting the yellow garage, the garage glows + +// scene.addOnIntersectionListener('can12', (type, otherNodeId) => { +// console.log('Can 12 placed!', type, otherNodeId); +// const visible = type === 'start'; +// scene.setChallengeEventValue('can12Intersects', visible); +// setNodeVisible('circle12', visible); +// }, 'circle12'); +`; -const baseScene = createBaseSceneSurfaceA(); + +const uprightCans = ` +// When a can is standing upright, the upright condition is met. + +// let startTime = Date.now(); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +// const startingOrientationInv = (nodeId) => Quaternion.inverse(RotationwUnits.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + + +scene.addOnRenderListener(() => { + // const currTime = Date.now(); + // const timeDiff = currTime - startTime; + const upright2 = yAngle('can2') < 5; + const upright9 = yAngle('can9') < 5; + const upright10 = yAngle('can10') < 5; + // if(timeDiff > 1000) { + // console.log('can6 angle: ', yAngle('can6')); + // startTime = currTime; + // } + scene.setChallengeEventValue('can2Upright', upright2); + scene.setChallengeEventValue('can9Upright', upright9); + scene.setChallengeEventValue('can10Upright', upright10); +}); +`; export const JBC_6: Scene = { ...baseScene, - name: tr('JBC 6'), - description: tr('Junior Botball Challenge 6: Load \'Em Up'), + name: { [LocalizedString.EN_US]: "JBC 6" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 6: Load 'Em Up`, + }, + scripts: { + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + garageIntersects: Script.ecmaScript("Garage Intersects", garageIntersects), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + greenGarage_geom: { + type: "box", + size: { + x: Distance.centimeters(20), + y: Distance.centimeters(0.1), + z: Distance.centimeters(20), + }, + }, + + blueGarage_geom: { + type: "box", + size: { + x: Distance.centimeters(20), + y: Distance.centimeters(0.1), + z: Distance.centimeters(20), + }, + }, + }, nodes: { ...baseScene.nodes, - 'can2': createCanNode(2), - 'can9': createCanNode(9), - 'can10': createCanNode(10), - } -}; \ No newline at end of file + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(0), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + greenGarage: { + type: "object", + geometryId: "greenGarage_geom", + name: { [LocalizedString.EN_US]: "Green Garage" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53.2), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + + blueGarage: { + type: "object", + geometryId: "blueGarage_geom", + name: { [LocalizedString.EN_US]: "Blue Garage" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(53.2), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, + ...baseScene.nodes, + can2: createCanNode(2), + can9: createCanNode(9), + can10: createCanNode(10), + }, +}; + diff --git a/src/simulator/definitions/scenes/jbc6c.ts b/src/simulator/definitions/scenes/jbc6c.ts index 224cb4e0..c7810a0a 100644 --- a/src/simulator/definitions/scenes/jbc6c.ts +++ b/src/simulator/definitions/scenes/jbc6c.ts @@ -1,10 +1,7 @@ import Scene from "../../../state/State/Scene"; import { Color } from '../../../state/State/Scene/Color'; -// import { RawVector3, RawQuaternion, RawReferenceFrame } from "../math"; -// import { Color3, StandardMaterial, GlowLayer } from 'babylonjs'; import Script from '../../../state/State/Scene/Script'; import { Distance } from "../../../util"; -import LocalizedString from '../../../util/LocalizedString'; import tr from '@i18n'; @@ -78,9 +75,9 @@ const uprightCans = ` // When a can is standing upright, the upright condition is met. // let startTime = Date.now(); -const EULER_IDENTITY = Rotation.Euler.identity(); -// const startingOrientationInv = (nodeId) => Quaternion.inverse(Rotation.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); -const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3.dot(Vector3.applyQuaternion(Vector3.Y, Rotation.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3.Y)); +const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); +// const startingOrientationInv = (nodeId) => Quaternion.inverse(RotationwUnits.toRawQuaternion(scene.nodes[nodeId].startingOrigin.orientation || EULER_IDENTITY)); +const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); scene.addOnRenderListener(() => { diff --git a/src/simulator/definitions/scenes/jbc7.ts b/src/simulator/definitions/scenes/jbc7.ts index 96cbcd2d..57cd7c3e 100644 --- a/src/simulator/definitions/scenes/jbc7.ts +++ b/src/simulator/definitions/scenes/jbc7.ts @@ -1,29 +1,267 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; +import LocalizedString from "../../../util/LocalizedString"; +import Script from "../../../state/State/Scene/Script"; +import { createCanNode, createBaseSceneSurfaceA } from "./jbcBase"; +import { Color } from "../../../state/State/Scene/Color"; +import { Distance } from "../../../util"; -import tr from '@i18n'; +const baseScene = createBaseSceneSurfaceA(); -import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; +const startBoxIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); -const baseScene = createBaseSceneSurfaceA(); +let count = 0; +scene.onBind = nodeId => { + + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + //count++; + //console.log(count); + + + if(type === 'start'){ + console.log(nodeId + " entered start box!"); + count++; + } + + else if (count != 0 && type === "end"){ + console.log(nodeId + " left start box :("); + count--; + } + else if (count > 3){ + count = 0; + } + + switch (count){ + case 0: + scene.setChallengeEventValue('canAIntersects', false); + scene.setChallengeEventValue('canBIntersects', false); + scene.setChallengeEventValue('canCIntersects', false); + break; + case 1: + scene.setChallengeEventValue('canAIntersects', true); + scene.setChallengeEventValue('canBIntersects', false); + scene.setChallengeEventValue('canCIntersects', false); + break; + case 2: + scene.setChallengeEventValue('canAIntersects', true); + scene.setChallengeEventValue('canBIntersects', true); + scene.setChallengeEventValue('canCIntersects', false); + break; + case 3: + scene.setChallengeEventValue('canAIntersects', true); + scene.setChallengeEventValue('canBIntersects', true); + scene.setChallengeEventValue('canCIntersects', true); + break; + + } + console.log("Intersecting Count: " + count + " (" +nodeId + ")"); + }, 'startBox'); + + +}; +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const enterStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const uprightCans = ` + +let count = 0; +console.log("Beginning Upright Count: " + count); +scene.onBind = nodeId => { + + + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); + const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + const upright = yAngle(nodeId) < 5; + + + if(upright && type === "start"){ + count++; + } + else if(upright && (count != 0) && type === "end"){ + count--; + } + else if(!upright && (count != 0) && type === "start"){ + count--; + } + switch (count){ + case 0: + scene.setChallengeEventValue('canAUpright', false); + scene.setChallengeEventValue('canBUpright', false); + scene.setChallengeEventValue('canCUpright', false); + break; + case 1: + scene.setChallengeEventValue('canAUpright', true); + scene.setChallengeEventValue('canBUpright', false); + scene.setChallengeEventValue('canCUpright', false); + break; + case 2: + scene.setChallengeEventValue('canAUpright', true); + scene.setChallengeEventValue('canBUpright', true); + scene.setChallengeEventValue('canCUpright', false); + break; + case 3: + scene.setChallengeEventValue('canAUpright', true); + scene.setChallengeEventValue('canBUpright', true); + scene.setChallengeEventValue('canCUpright', true); + break; + + } + console.log("Upright Count: " + count + " (" +nodeId + ")"); + + + + }, 'startBox'); +}; +`; export const JBC_7: Scene = { ...baseScene, - name: tr('JBC 7'), - description: tr('Junior Botball Challenge 7: Bulldozer Mania'), + name: { [LocalizedString.EN_US]: "JBC 7" }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 7: Bulldozer Mania`, + }, + scripts: { + startBoxIntersects: Script.ecmaScript( + "Start Box Intersects", + startBoxIntersects + ), + uprightCans: Script.ecmaScript("Upright Cans", uprightCans), + leftStartBox: Script.ecmaScript("Robot Left Start", leftStartBox), + enterStartBox: Script.ecmaScript("Robot Reentered Start", enterStartBox), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: "box", + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(30), + }, + }, + }, + nodes: { + mainSurface: { + type: "object", + geometryId: "mainSurface_geom", + name: { [LocalizedString.EN_US]: "Mat Surface" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: "basic", + color: { + type: "color3", + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: "object", + geometryId: "startBox_geom", + name: { [LocalizedString.EN_US]: "Start Box" }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-3), + }, + }, + material: { + type: "pbr", + emissive: { + type: "color3", + color: Color.rgb(255, 255, 255), + }, + }, + }, ...baseScene.nodes, - 'can1': createCanNode(1), - 'can2': createCanNode(2), - 'can3': createCanNode(3), - 'can4': createCanNode(4), - 'can5': createCanNode(5), - 'can6': createCanNode(6), - 'can7': createCanNode(7), - 'can8': createCanNode(8), - 'can9': createCanNode(9), - 'can10': createCanNode(10), - 'can11': createCanNode(11), - 'can12': createCanNode(12), - } -}; \ No newline at end of file + can1: { + ...createCanNode(1), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can2: { + ...createCanNode(2), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can3: { + ...createCanNode(3), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can4: { + ...createCanNode(4), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can5: { + ...createCanNode(5), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can6: { + ...createCanNode(6), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can7: { + ...createCanNode(7), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can8: { + ...createCanNode(8), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can9: { + ...createCanNode(9), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can10: { + ...createCanNode(10), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can11: { + ...createCanNode(11), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + can12: { + ...createCanNode(12), + scriptIds: ["startBoxIntersects", "uprightCans"], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc7b.ts b/src/simulator/definitions/scenes/jbc7b.ts index e8269023..ebf88a45 100644 --- a/src/simulator/definitions/scenes/jbc7b.ts +++ b/src/simulator/definitions/scenes/jbc7b.ts @@ -1,41 +1,518 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import { ReferenceFramewUnits } from '../../../util/math/unitMath'; -import { Distance } from "../../../util"; +import { Distance } from '../../../util'; import LocalizedString from '../../../util/LocalizedString'; - +import Script from '../../../state/State/Scene/Script'; import { createBaseSceneSurfaceA, createCanNode } from './jbcBase'; - -import tr from '@i18n'; +import { Color } from '../../../state/State/Scene/Color'; const baseScene = createBaseSceneSurfaceA(); +const startBoxIntersects = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); +let circles = []; +let count = 0; +scene.onBind = nodeId => { + + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + //count++; + //console.log(count); + console.log("Circles = " + circles); + + if(count == 0){ + circles = []; + } + + if(type === 'start' && (circles.includes(otherNodeId) == false)){ + console.log(nodeId + " is on " + otherNodeId); + + + setNodeVisible(otherNodeId, true); + circles.push(otherNodeId); + count++; + + } + + + if (count != 0 && type === "end"){ + if((circles.includes(otherNodeId) == true)){ + console.log(nodeId + " left " + otherNodeId +" :("); + + setNodeVisible(otherNodeId, false); + const removeIndex = circles.indexOf(otherNodeId); + const x = circles.splice(removeIndex,1); + count--; + } + } + else if (count > 5){ + count = 0; + } + + switch (count){ + case 0: + scene.setChallengeEventValue('canAIntersects', false); + scene.setChallengeEventValue('canBIntersects', false); + scene.setChallengeEventValue('canCIntersects', false); + scene.setChallengeEventValue('canDIntersects', false); + scene.setChallengeEventValue('canEIntersects', false); + break; + case 1: + scene.setChallengeEventValue('canAIntersects', true); + scene.setChallengeEventValue('canBIntersects', false); + scene.setChallengeEventValue('canCIntersects', false); + scene.setChallengeEventValue('canDIntersects', false); + scene.setChallengeEventValue('canEIntersects', false); + break; + case 2: + scene.setChallengeEventValue('canBIntersects', true); + scene.setChallengeEventValue('canCIntersects', false); + scene.setChallengeEventValue('canDIntersects', false); + scene.setChallengeEventValue('canEIntersects', false); + break; + case 3: + scene.setChallengeEventValue('canCIntersects', true); + scene.setChallengeEventValue('canDIntersects', false); + scene.setChallengeEventValue('canEIntersects', false); + break; + case 4: + + scene.setChallengeEventValue('canDIntersects', true); + scene.setChallengeEventValue('canEIntersects', false); + break; + case 5: + + scene.setChallengeEventValue('canEIntersects', true); + break; + + } + console.log("Intersecting Count: " + count + " (" +nodeId + ")"); + }, ['circle1', 'circle2', 'circle3', 'circle4', 'circle5', 'circle6', 'circle7']); + + +}; +`; + +const leftStartBox = ` + +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot left start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('leaveStartBox', type === 'end'); + } + +}, 'startBox'); +`; + +const enterStartBox = ` +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot returned start box!', type, otherNodeId); + if(scene.programStatus === 'running'){ + scene.setChallengeEventValue('returnStartBox', type === 'start'); + } +}, 'startBox'); +`; + +const uprightCans = ` +let circles = []; +let count = 0; +console.log("Beginning Upright Count: " + count); +scene.onBind = nodeId => { + + + scene.addOnIntersectionListener(nodeId, (type, otherNodeId) => { + const EULER_IDENTITY = RotationwUnits.EulerwUnits.identity(); + const yAngle = (nodeId) => 180 / Math.PI * Math.acos(Vector3wUnits.dot(Vector3wUnits.applyQuaternion(Vector3wUnits.Y, RotationwUnits.toRawQuaternion(scene.nodes[nodeId].origin.orientation || EULER_IDENTITY)), Vector3wUnits.Y)); + const upright = yAngle(nodeId) < 5; + + if(count == 0){ + circles = []; + } + if(upright && type === "start" && (circles.includes(otherNodeId) == false)){ + count++; + circles.push(otherNodeId); + if(!upright && (count != 0) && type === "end"){ + count--; + const removeIndex = circles.indexOf(otherNodeId); + const x = circles.splice(removeIndex,1); + } + } + else if(upright && (count != 0) && type === "end"){ + + if((circles.includes(otherNodeId) == true)){ + count--; + const removeIndex = circles.indexOf(otherNodeId); + const x = circles.splice(removeIndex,1); + } + + } + + switch (count){ + case 0: + scene.setChallengeEventValue('canAUpright', false); + scene.setChallengeEventValue('canBUpright', false); + scene.setChallengeEventValue('canCUpright', false); + scene.setChallengeEventValue('canDUpright', false); + scene.setChallengeEventValue('canEUpright', false); + break; + case 1: + scene.setChallengeEventValue('canAUpright', true); + scene.setChallengeEventValue('canBUpright', false); + scene.setChallengeEventValue('canCUpright', false); + scene.setChallengeEventValue('canDUpright', false); + scene.setChallengeEventValue('canEUpright', false); + break; + case 2: + scene.setChallengeEventValue('canBUpright', true); + scene.setChallengeEventValue('canCUpright', false); + scene.setChallengeEventValue('canDUpright', false); + scene.setChallengeEventValue('canEUpright', false); + break; + case 3: + scene.setChallengeEventValue('canCUpright', true); + scene.setChallengeEventValue('canDUpright', false); + scene.setChallengeEventValue('canEUpright', false); + break; + case 4: + scene.setChallengeEventValue('canDUpright', true); + scene.setChallengeEventValue('canEUpright', false); + break; + case 5: + scene.setChallengeEventValue('canEUpright', true); + break; + + + } + console.log("Upright Count: " + count + " (" +nodeId + ") in " + otherNodeId); + + + + }, ['circle1', 'circle2', 'circle3', 'circle4', 'circle5', 'circle6', 'circle7']); +}; +`; const ROBOT_ORIGIN: ReferenceFramewUnits = { ...baseScene.nodes['robot'].origin, position: { ...baseScene.nodes['robot'].origin.position, - z: Distance.centimeters(-8) + z: Distance.centimeters(-8), }, }; export const JBC_7B: Scene = { ...baseScene, - name: tr('JBC 7B'), - description: tr('Junior Botball Challenge 7B: Cover Your Bases'), + name: { [LocalizedString.EN_US]: 'JBC 7B' }, + description: { + [LocalizedString.EN_US]: `Junior Botball Challenge 7B: Cover Your Bases`, + }, + scripts: { + startBoxIntersects: Script.ecmaScript( + 'Start Box Intersects', + startBoxIntersects + ), + uprightCans: Script.ecmaScript('Upright Cans', uprightCans), + leftStartBox: Script.ecmaScript('Robot Left Start', leftStartBox), + enterStartBox: Script.ecmaScript('Robot Reentered Start', enterStartBox), + }, + geometry: { + ...baseScene.geometry, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(30), + }, + }, + circle1_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle2_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle3_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle4_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle5_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle6_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + circle7_geom: { + type: 'cylinder', + radius: Distance.centimeters(3), + height: Distance.centimeters(0.1), + }, + }, nodes: { ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-3), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle1: { + type: 'object', + geometryId: 'circle1_geom', + name: { [LocalizedString.EN_US]: 'Circle 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(22.7), // can 1 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(35.2), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle2: { + type: 'object', + geometryId: 'circle2_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28.8), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle3: { + type: 'object', + geometryId: 'circle3_geom', + name: { [LocalizedString.EN_US]: 'Circle 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16.2), // can 3 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(25.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle4: { + type: 'object', + geometryId: 'circle4_geom', + name: { [LocalizedString.EN_US]: 'Circle 4' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 4 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(42.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle5: { + type: 'object', + geometryId: 'circle5_geom', + name: { [LocalizedString.EN_US]: 'Circle 5' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(14.3), // can 5 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle6: { + type: 'object', + geometryId: 'circle6_geom', + name: { [LocalizedString.EN_US]: 'Circle 6' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 6 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle7: { + type: 'object', + geometryId: 'circle7_geom', + name: { [LocalizedString.EN_US]: 'Circle 7' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-13.8), // can 7 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, // The normal starting position of the robot covers the tape // Start the robot back a bit so that a can fits on the tape in front of the robot - 'robot': { + robot: { ...baseScene.nodes['robot'], startingOrigin: ROBOT_ORIGIN, - origin: ROBOT_ORIGIN - }, - 'can1': createCanNode(1, { x: Distance.centimeters(24), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can2': createCanNode(2, { x: Distance.centimeters(16), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can3': createCanNode(3, { x: Distance.centimeters(8), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can4': createCanNode(4, { x: Distance.centimeters(0), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can5': createCanNode(5, { x: Distance.centimeters(-8), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can6': createCanNode(7, { x: Distance.centimeters(-16), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), - 'can7': createCanNode(6, { x: Distance.centimeters(-24), y: Distance.centimeters(0), z: Distance.centimeters(15.5) }), + origin: ROBOT_ORIGIN, + }, + can1: { + ...createCanNode(1, { + x: Distance.centimeters(24), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can2: { + ...createCanNode(2, { + x: Distance.centimeters(16), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can3: { + ...createCanNode(3, { + x: Distance.centimeters(8), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can4: { + ...createCanNode(4, { + x: Distance.centimeters(0), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can5: { + ...createCanNode(5, { + x: Distance.centimeters(-8), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can6: { + ...createCanNode(5, { + x: Distance.centimeters(-16), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, + can7: { + ...createCanNode(7, { + x: Distance.centimeters(-24), + y: Distance.centimeters(0), + z: Distance.centimeters(15.5), + }), + scriptIds: ['startBoxIntersects', 'uprightCans'], + }, }, -}; \ No newline at end of file +}; diff --git a/src/simulator/definitions/scenes/jbc8.ts b/src/simulator/definitions/scenes/jbc8.ts index c1ba6d0c..08db3a07 100644 --- a/src/simulator/definitions/scenes/jbc8.ts +++ b/src/simulator/definitions/scenes/jbc8.ts @@ -1,14 +1,523 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; +import Script from '../../../state/State/Scene/Script'; +import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import { Distance } from '../../../util'; -import { createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const beginsStart = ` -const baseScene = createBaseSceneSurfaceA(); +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot begins in start box!', type, otherNodeId); + if(type === "start"){ + scene.setChallengeEventValue('start', true); + } + +}, 'startBox'); +`; + +const passedSide = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); +let circles = ['circle1','circle2','circle3','circle4','circle5','circle6','circle7','circle8']; +let count = 0; +let position = 0; + +scene.onBind = nodeId => { + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + const visible = type === 'start'; + if(otherNodeId == "startBox"){ + count = 0; + position = 0; + } + + if(type === "start" && (circles.includes(otherNodeId) == false)){ + position++; + console.log(count + ":" + otherNodeId + ":" + type + ":Position:" +position ); + } + + if(type==="start" && (count == position -1) && (otherNodeId == "n" +position)){ + count++; + console.log(count + ":" + otherNodeId + ":" + type); + + } + + switch(count){ + case 1: + if(otherNodeId == "n1"){ + setNodeVisible('circle1',true); + scene.setChallengeEventValue('passed1', true); + } + break; + case 2: + if(otherNodeId == "n2"){ + setNodeVisible('circle2',true); + scene.setChallengeEventValue('passed2', true); + } + break; + case 3: + if(otherNodeId == "n3"){ + setNodeVisible('circle3',true); + scene.setChallengeEventValue('passed3', true); + } + break; + case 4: + if(otherNodeId == "n4"){ + setNodeVisible('circle4',true); + scene.setChallengeEventValue('passed4', true); + } + break; + case 5: + if(otherNodeId == "n5"){ + setNodeVisible('circle5',true); + scene.setChallengeEventValue('passed5', true); + } + break; + case 6: + if(otherNodeId == "n6"){ + setNodeVisible('circle6',true); + scene.setChallengeEventValue('passed6', true); + } + break; + case 7: + if(otherNodeId == "n7"){ + setNodeVisible('circle7',true); + scene.setChallengeEventValue('passed7', true); + } + break; + case 8: + if(otherNodeId == "n8"){ + setNodeVisible('circle8',true); + scene.setChallengeEventValue('passed8', true); + } + break; + } + + + if(position == 0 ){ + count = 0; + } + + + }, ['startBox', 'circle1','circle2','circle3','circle4','circle5','circle6','circle7','circle8', + 'n1','n2','n3','n4','n5','n6','n7','n8']); +}; +`; +// 'n2','n3','n4','n5','n6','n7','n8' export const JBC_8: Scene = { ...baseScene, - name: tr('JBC 8'), - description: tr('Junior Botball Challenge 8: Serpentine'), -}; \ No newline at end of file + name: { [LocalizedString.EN_US]: 'JBC 8' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 8: Serpentine', + }, + scripts: { + passedSide: Script.ecmaScript('Passed Side', passedSide), + beginsStart: Script.ecmaScript('Robot Begins In Start', beginsStart), + }, + geometry: { + ...baseScene.geometry, + circle_geom: { + type: 'cylinder', + radius: Distance.centimeters(1), + height: Distance.centimeters(0.1), + }, + n_geom: { + type: 'cylinder', + radius: Distance.centimeters(0.01), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + }, + nodes: { + ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-14), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle1: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(22.7), // can 1 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(35.2), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(23.5), // can 1 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(32.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle2: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28.8), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(26.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle3: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16.2), // can 3 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(25.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16.2), // can 3 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(22.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle4: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 4' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 4 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(42.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n4: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 4' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-3), // can 4 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(45), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle5: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 5' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(14.3), // can 5 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n5: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 5' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(17), // can 5 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(59), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle6: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 6' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 6 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(57.2), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n6: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 6' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-6), // can 6 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(60), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle7: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 7' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-13.8), // can 7 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n7: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 7' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-18), // can 7 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(59), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle8: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 8' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-26), // can 8 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n8: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 8' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-26), // can 8 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(62), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can8: { + ...createCanNode(8, { + x: Distance.centimeters(-26), // can 8 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65.5), + },false,false), + scriptIds: ['passedSide'], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbc8b.ts b/src/simulator/definitions/scenes/jbc8b.ts index e1b48558..cf46ff62 100644 --- a/src/simulator/definitions/scenes/jbc8b.ts +++ b/src/simulator/definitions/scenes/jbc8b.ts @@ -1,14 +1,385 @@ -import Scene from "../../../state/State/Scene"; +import Scene from '../../../state/State/Scene'; import LocalizedString from '../../../util/LocalizedString'; +import Script from '../../../state/State/Scene/Script'; +import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { Color } from '../../../state/State/Scene/Color'; +import { Distance } from '../../../util'; -import { createBaseSceneSurfaceA } from './jbcBase'; +const baseScene = createBaseSceneSurfaceA(); -import tr from '@i18n'; +const beginsStart = ` -const baseScene = createBaseSceneSurfaceA(); +scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + console.log('Robot begins in start box!', type, otherNodeId); + if(type === "start"){ + scene.setChallengeEventValue('start', true); + } + +}, 'startBox'); +`; + +const passedSide = ` +const setNodeVisible = (nodeId, visible) => scene.setNode(nodeId, { + ...scene.nodes[nodeId], + visible +}); +let circles = ['circle1','circle2','circle3','circle4','circle5']; +let count = 0; +let position = 0; + +scene.onBind = nodeId => { + + scene.addOnIntersectionListener('robot', (type, otherNodeId) => { + const visible = type === 'start'; + if(otherNodeId == "startBox"){ + count = 0; + position = 0; + } + + if(type === "start" && (circles.includes(otherNodeId) == false)){ + position++; + console.log(count + ":" + otherNodeId + ":" + type + ":Position:" +position ); + } + + if(type==="start" && (count == position -1) && (otherNodeId == "n" +position)){ + count++; + console.log(count + ":" + otherNodeId + ":" + type); + + } + + switch(count){ + case 1: + if(otherNodeId == "n1"){ + setNodeVisible('circle1',true); + scene.setChallengeEventValue('passed1', true); + } + break; + case 2: + if(otherNodeId == "n2"){ + setNodeVisible('circle2',true); + scene.setChallengeEventValue('passed2', true); + } + break; + case 3: + if(otherNodeId == "n3"){ + setNodeVisible('circle3',true); + scene.setChallengeEventValue('passed3', true); + } + break; + case 4: + if(otherNodeId == "n4"){ + setNodeVisible('circle4',true); + scene.setChallengeEventValue('passed4', true); + } + break; + case 5: + if(otherNodeId == "n5"){ + setNodeVisible('circle5',true); + scene.setChallengeEventValue('passed5', true); + } + break; + } + + + if(position == 0 ){ + count = 0; + } + + + }, ['startBox', 'circle1','circle2','circle3','circle4','circle5', + 'n1','n2','n3','n4','n5']); +}; + +`; export const JBC_8B: Scene = { ...baseScene, - name: tr('JBC 8B'), - description: tr('Junior Botball Challenge 8B: Serpentine Jr.'), -}; \ No newline at end of file + name: { [LocalizedString.EN_US]: 'JBC 8B' }, + description: { + [LocalizedString.EN_US]: 'Junior Botball Challenge 8B: Serpentine Jr.', + }, + scripts: { + passedSide: Script.ecmaScript('Passed Side', passedSide), + beginsStart: Script.ecmaScript('Robot Begins In Start', beginsStart), + }, + geometry: { + ...baseScene.geometry, + circle_geom: { + type: 'cylinder', + radius: Distance.centimeters(1), + height: Distance.centimeters(0.1), + }, + n_geom: { + type: 'cylinder', + radius: Distance.centimeters(0.01), + height: Distance.centimeters(0.1), + }, + mainSurface_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.meters(3.54), + }, + }, + startBox_geom: { + type: 'box', + size: { + x: Distance.meters(3.54), + y: Distance.centimeters(0.1), + z: Distance.centimeters(0), + }, + }, + }, + nodes: { + ...baseScene.nodes, + mainSurface: { + type: 'object', + geometryId: 'mainSurface_geom', + name: { [LocalizedString.EN_US]: 'Mat Surface' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.inches(19.75), + }, + }, + material: { + type: 'basic', + color: { + type: 'color3', + color: Color.rgb(0, 0, 0), + }, + }, + }, + startBox: { + type: 'object', + geometryId: 'startBox_geom', + name: { [LocalizedString.EN_US]: 'Start Box' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), + y: Distance.centimeters(-6.9), + z: Distance.centimeters(-14), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle1: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(22.7), // can 1 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(35.2), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n1: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 1' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(23.5), // can 1 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(32.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle2: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(28.8), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n2: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 2' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 2 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(26.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle3: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16.2), // can 3 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(25.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n3: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 3' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-16.2), // can 3 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(22.5), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle4: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 4' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(0), // can 4 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(42.7), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n4: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 4' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(-3), // can 4 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(45), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + circle5: { + type: 'object', + geometryId: 'circle_geom', + name: { [LocalizedString.EN_US]: 'Circle 5' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(14.3), // can 5 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(56.9), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + n5: { + type: 'object', + geometryId: 'n_geom', + name: { [LocalizedString.EN_US]: 'Circle 5' }, + visible: false, + origin: { + position: { + x: Distance.centimeters(17), // can 5 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(59), + }, + }, + material: { + type: 'pbr', + emissive: { + type: 'color3', + color: Color.rgb(255, 255, 255), + }, + }, + }, + can8: { + ...createCanNode(8, { + x: Distance.centimeters(-26), // can 8 + y: Distance.centimeters(-6.9), + z: Distance.centimeters(65.5), + },false,false), + scriptIds: ['passedSide'], + }, + }, +}; diff --git a/src/simulator/definitions/scenes/jbcBase.ts b/src/simulator/definitions/scenes/jbcBase.ts index 8e0055e6..457c7c03 100644 --- a/src/simulator/definitions/scenes/jbcBase.ts +++ b/src/simulator/definitions/scenes/jbcBase.ts @@ -4,7 +4,6 @@ import Node from "../../../state/State/Scene/Node"; import Camera from "../../../state/State/Scene/Camera"; import Scene from "../../../state/State/Scene"; import AbstractRobot from '../../../programming/AbstractRobot'; -import LocalizedString from '../../../util/LocalizedString'; import Author from '../../../db/Author'; import tr from '@i18n'; diff --git a/src/simulator/definitions/scenes/jbcSandboxA.ts b/src/simulator/definitions/scenes/jbcSandboxA.ts index fea03491..1e66ce6e 100644 --- a/src/simulator/definitions/scenes/jbcSandboxA.ts +++ b/src/simulator/definitions/scenes/jbcSandboxA.ts @@ -1,8 +1,6 @@ import Scene from "../../../state/State/Scene"; -import Script from '../../../state/State/Scene/Script'; import { ReferenceFramewUnits, RotationwUnits } from "../../../util/math/unitMath"; import { Distance } from "../../../util"; -import LocalizedString from '../../../util/LocalizedString'; import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; diff --git a/src/simulator/definitions/scenes/jbcSandboxB.ts b/src/simulator/definitions/scenes/jbcSandboxB.ts index 5d9468d4..9a3abdc1 100644 --- a/src/simulator/definitions/scenes/jbcSandboxB.ts +++ b/src/simulator/definitions/scenes/jbcSandboxB.ts @@ -1,5 +1,4 @@ import Scene from "../../../state/State/Scene"; -import LocalizedString from '../../../util/LocalizedString'; import { createBaseSceneSurfaceB } from './jbcBase'; diff --git a/src/simulator/definitions/scenes/lightSensorTest.ts b/src/simulator/definitions/scenes/lightSensorTest.ts index e61db47b..f8fbc59e 100644 --- a/src/simulator/definitions/scenes/lightSensorTest.ts +++ b/src/simulator/definitions/scenes/lightSensorTest.ts @@ -1,11 +1,9 @@ import Scene from "../../../state/State/Scene"; -import Node from '../../../state/State/Scene/Node'; import Script from '../../../state/State/Scene/Script'; import { ReferenceFramewUnits, RotationwUnits, Vector3wUnits } from "../../../util/math/unitMath"; -import { Distance } from "../../../util"; import LocalizedString from '../../../util/LocalizedString'; -import { createCanNode, createBaseSceneSurfaceA } from './jbcBase'; +import { createBaseSceneSurfaceA } from './jbcBase'; const baseScene = createBaseSceneSurfaceA(); diff --git a/src/state/State/Challenge/Expr.ts b/src/state/State/Challenge/Expr.ts index 13281ee0..2f563e48 100644 --- a/src/state/State/Challenge/Expr.ts +++ b/src/state/State/Challenge/Expr.ts @@ -21,7 +21,7 @@ namespace Expr { eventId: string; } - namespace Event { + export namespace Event { export const evaluate = (event: Event, context: EvaluationContext): boolean => { const eventState = context.eventStates[event.eventId]; return eventState === undefined ? false : eventState; diff --git a/src/state/State/Scene/index.ts b/src/state/State/Scene/index.ts index 00aee8d7..d544cd0f 100644 --- a/src/state/State/Scene/index.ts +++ b/src/state/State/Scene/index.ts @@ -104,8 +104,9 @@ namespace Scene { const queue = [...rootNodes]; const visited = new Set(); const ret: string[] = []; + - while (visited.size < Object.keys(scene.nodes).length) { + while (queue.length > 0) { const next = queue.shift(); if (visited.has(next)) continue; visited.add(next); diff --git a/src/state/reducer/challenges.ts b/src/state/reducer/challenges.ts index fc23ce9f..c29d814f 100644 --- a/src/state/reducer/challenges.ts +++ b/src/state/reducer/challenges.ts @@ -12,10 +12,33 @@ import LocalizedString from '../../util/LocalizedString'; import db from '../../db'; import Selector from '../../db/Selector'; -import test from '../../simulator/definitions/challenges/test'; +import jbc1 from "../../simulator/definitions/challenges/jbc1"; +import jbc2 from "../../simulator/definitions/challenges/jbc2"; +import jbc2b from "../../simulator/definitions/challenges/jbc2b"; +import jbc2c from "../../simulator/definitions/challenges/jbc2c"; +import jbc2d from "../../simulator/definitions/challenges/jbc2d"; +import jbc3 from "../../simulator/definitions/challenges/jbc3"; +import jbc4 from "../../simulator/definitions/challenges/jbc4"; +import jbc4b from "../../simulator/definitions/challenges/jbc4b"; +import jbc5 from "../../simulator/definitions/challenges/jbc5"; +import jbc6 from "../../simulator/definitions/challenges/jbc6"; import jbc6c from "../../simulator/definitions/challenges/jbc6c"; - - +import jbc7 from "../../simulator/definitions/challenges/jbc7"; +import jbc7b from "../../simulator/definitions/challenges/jbc7b"; +import jbc8 from "../../simulator/definitions/challenges/jbc8"; +import jbc8b from "../../simulator/definitions/challenges/jbc8b"; +import jbc10 from "../../simulator/definitions/challenges/jbc10"; +import jbc10b from "../../simulator/definitions/challenges/jbc10b"; +import jbc12 from "../../simulator/definitions/challenges/jbc12"; +import jbc13 from "../../simulator/definitions/challenges/jbc13"; +import jbc15b from "../../simulator/definitions/challenges/jbc15b"; +import jbc17 from "../../simulator/definitions/challenges/jbc17"; +import jbc17b from "../../simulator/definitions/challenges/jbc17b"; +import jbc19 from "../../simulator/definitions/challenges/jbc19"; +import jbc20 from "../../simulator/definitions/challenges/jbc20"; +import jbc21 from "../../simulator/definitions/challenges/jbc21"; +import jbc22 from "../../simulator/definitions/challenges/jbc22"; +import test from '../../simulator/definitions/challenges/test'; export namespace ChallengesAction { export interface LoadChallenge { @@ -128,6 +151,106 @@ const DEFAULT_CHALLENGES: Challenges = { value: jbc6c, brief: ChallengeBrief.fromChallenge(jbc6c), }), + 'jbc1': Async.loaded({ + value: jbc1, + brief: ChallengeBrief.fromChallenge(jbc1), + }), + 'jbc2': Async.loaded({ + value: jbc2, + brief: ChallengeBrief.fromChallenge(jbc2), + }), + 'jbc2b': Async.loaded({ + value: jbc2b, + brief: ChallengeBrief.fromChallenge(jbc2b), + }), + 'jbc2c': Async.loaded({ + value: jbc2c, + brief: ChallengeBrief.fromChallenge(jbc2c), + }), + 'jbc2d': Async.loaded({ + value: jbc2d, + brief: ChallengeBrief.fromChallenge(jbc2d), + }), + 'jbc3': Async.loaded({ + value: jbc3, + brief: ChallengeBrief.fromChallenge(jbc3), + }), + 'jbc5': Async.loaded({ + value: jbc5, + brief: ChallengeBrief.fromChallenge(jbc5), + }), + 'jbc4': Async.loaded({ + value: jbc4, + brief: ChallengeBrief.fromChallenge(jbc4), + }), + 'jbc4b': Async.loaded({ + value: jbc4b, + brief: ChallengeBrief.fromChallenge(jbc4b), + }), + 'jbc6': Async.loaded({ + value: jbc6, + brief: ChallengeBrief.fromChallenge(jbc6), + }), + 'jbc7': Async.loaded({ + value: jbc7, + brief: ChallengeBrief.fromChallenge(jbc7), + }), + 'jbc7b': Async.loaded({ + value: jbc7b, + brief: ChallengeBrief.fromChallenge(jbc7b), + }), + 'jbc8': Async.loaded({ + value: jbc8, + brief: ChallengeBrief.fromChallenge(jbc8), + }), + 'jbc8b': Async.loaded({ + value: jbc8b, + brief: ChallengeBrief.fromChallenge(jbc8b), + }), + 'jbc10': Async.loaded({ + value: jbc10, + brief: ChallengeBrief.fromChallenge(jbc10), + }), + 'jbc10b': Async.loaded({ + value: jbc10b, + brief: ChallengeBrief.fromChallenge(jbc10b), + }), + 'jbc12': Async.loaded({ + value: jbc12, + brief: ChallengeBrief.fromChallenge(jbc12), + }), + 'jbc13': Async.loaded({ + value: jbc13, + brief: ChallengeBrief.fromChallenge(jbc13), + }), + 'jbc15b': Async.loaded({ + value: jbc15b, + brief: ChallengeBrief.fromChallenge(jbc15b), + }), + 'jbc17': Async.loaded({ + value: jbc17, + brief: ChallengeBrief.fromChallenge(jbc17), + }), + 'jbc17b': Async.loaded({ + value: jbc17b, + brief: ChallengeBrief.fromChallenge(jbc17b), + }), + 'jbc19': Async.loaded({ + value: jbc19, + brief: ChallengeBrief.fromChallenge(jbc19), + }), + 'jbc20': Async.loaded({ + value: jbc20, + brief: ChallengeBrief.fromChallenge(jbc20), + }), + 'jbc21': Async.loaded({ + value: jbc21, + brief: ChallengeBrief.fromChallenge(jbc21), + }), + 'jbc22': Async.loaded({ + value: jbc22, + brief: ChallengeBrief.fromChallenge(jbc22), + }), }; const create = async (challengeId: string, next: Async.Creating) => { diff --git a/static/Click Here.png b/static/Click Here.png new file mode 100644 index 00000000..1affa21e Binary files /dev/null and b/static/Click Here.png differ