If you don’t have client id and client secret, call postApps at first. (Alternatively, look in the web client, under the development section of your mastodon profile settings)
importWeb.Hastodon
appRes <- postApps "mastodon.social" "HastodonClientApp"
case appRes of
Right app -> do
let clientId = oauthClientClientId app
let clientSecret = oauthClientClientSecret app
Fill client id, client secret, the email address used to sign up for the instance and password, then call functions.
importWeb.Hastodonmain::IO()
main =dolet clientId ="???"let clientSecret ="???"let email ="???"let password ="???"
maybeClient <- mkHastodonClient clientId clientSecret email password "mastodon.social"case maybeClient ofJust client ->do
timeline <- getAccountById client 93150print timeline
result <- postStatus client "test toot from hastodon!"print result
Nothing->doputStrLn"Failed to log in. Be careful regarding the spelling of your email and password."
Streaming
Streaming requires a little more ceremony, as well as familiarity with the Conduit library.
{-# LANGUAGE OverloadedStrings #-}
importWeb.HastodonimportConduitimportqualifiedData.ByteString.Char8asBSmain::IO()
main =dolet inst ="mastodon.social"let token ="???"-- from /settings/applicationslet client =HastodonClient instance token -- or use mkHastodonClient as above
runConduitRes $ streamUser client .| mapC showSR .| stdoutC
where showSR (SNotification n) ="got notification: "`BS.append` (sb n) `BS.append`"\n"
showSR (SUpdate s) ="got status: "`BS.append` (sb s) `BS.append`"\n"
showSR (SDelete i) ="got delete: "`BS.append` (BS.pack i) `BS.append`"\n"
showSR Thump="got thump\n"
sb v =BS.pack $show v
1.3 position() function to read the current position of a servo.
1.2 Destructor to remove the SMS object from the list. Allows dynamic configuration in general purpose board.
1.1.2 Fix a mistake in the documentation.
1.1.1 Live settings example
1.1 Added methods to support live min max settings
1.0.6 Release to fix the problem of the duplicated 1.0.5. Nothing new
1.0.5 Minor fix in one of the accessor name
1.0.4 Added accessors to get almost all attributes of a SMS object
1.0.3 Added a method to do a mirror at time = .5
1.0.2 Default min and max have been changed to 1000 and 2000. More accurate SMSSmoothBounce trajectory. Fixed a problem with the initial position. Added PushButton example.
1.0.1 Fix a typo in the library.properties
1.0 Initial release.
Description
SlowMotionServo provides a way to drive one or many servos slowly. Instead of
setting the position, each servo has 2 trajectories, ie 2 functions angle(t)
where t is the time. The first function is used to compute the angle of the
servo when travelling from minimum to maximum angle and the second one is used
when travelling from the maximum to the minimum angle.
The function is normalized between 0.0 and 1.0, both for the angle and the time.
So the angle varies from the minimum angle set for the servo to the maximum
angle set for the servo so that the minimum angle corresponds to 0.0 and the
maximum angle corresponds to 1.0. time 0.0 is the start of the movement and time
1.0 is the end of the movement. By default the speed is set so that travelling
from the minimum angle to the maximum angle takes 10s. The same exists when
travelling from the maximum to the minimum angle and both travels have their
own speed setting.
3 trajectories are available and you can add more trajectories by deriving from
the class SlowMotionServo:
sinusoidal trajectory with a bounce. When t <= 0.79, angle = 1.0 – cos(t * PI))/1.8. Otherwise, timeOff = 10.0 * (t – 0.55) and angle = 0.834 + 1.0 / (timeOff * timeOff)
Using the library
As usual, you have to include it at the beginning of your sketch but you also
have to include the Servo library:
#include <Servo.h>
#include <SlowMotionServo.h>
Then you have to instantiate as many object as servos you want to drive. For
that you choose what kind of trajectory you want:
SMSLinear is the class with a linear trajectory. SMSSmooth is the class with a
sinusoidal trajectory and SMSSmoothBounce is the class with a sinusoidal
trajectory with a bounce.
SMSLinear myServo; /* Servo with linear trajectory */
The following functions are available:
setMin(min)
Set the minimum angle of the servo. The angle is expressed in its equivalency
in microseconds. The value can range from 544 to 2400. A value lower than 544
will be reset to 544 and a value greater than 2400 will be reset to 2400.
If the value is greater than the maximum angle it is reset to the maximum
angle.
setMax(max)
Set the maximum angle of the servo. The angle is expressed in its equivalency
in microseconds. The value can range from 544 to 2400. A value lower than 544
will be reset to 544 and a value greater than 2400 will be reset to 2400.
If the value is lower than the minimum angle it is reset to the minimum
angle.
setMinMax(min, max)
Set the minimum and maximum angles of the servo. The angle is expressed in
its equivalency in microseconds. The value can range from 544 to 2400.
A value lower than 544 will be reset to 544 and a value greater than 2400
will be reset to 2400.
If the minimum angle is greater than the maximum angle, both angles are set
to the average value. For instance if you set the minimum angle to 2000 and
the maximum angle to 1000, both angles will be set to 1500.
setPin(pin)
Set the pin to which the servo is attached.
setMinToMaxSpeed(speed)
Set the speed of the servo when travelling from the minimum to the maximum
angle. speed is a floating point number. A speed of 1.0 corresponds to a
10s travelling.
setMaxToMinSpeed(speed)
Set the speed of the servo when travelling from the maximum to the minimum
angle. speed is a floating point number. A speed of 1.0 corresponds to a
10s travelling.
setSpeed(speed)
Set the speed of the servo when travelling from the minimum to the maximum
angle and from the maximum to the minimum angle.
speed is a floating point number. A speed of 1.0 corresponds to a
10s travelling.
setInitialPosition(position)
Set the initial position of the servo. The position is a floating point number
ranging from 0.0 to 1.0. If the value is greater than 1.0, ti is reset to 1.0
and if lower than 0.0, it is reset to 0.0
setReverted(reverted)
Reverse the movement. By default reverted is false. If set to true, the trajectories are mirrored across an axis at time = 0.5.
goTo(position)
Go to the specified position by following the trajectory.
The position is a floating point number
ranging from 0.0 to 1.0. If the value is greater than 1.0, ti is reset to 1.0
and if lower than 0.0, it is reset to 0.0
goToMin()
Equivalent to goTo(0.0)
goToMax()
Equivalent to goTo(1.0)
setDetachAtMin(detach)
detach is a boolean. If true, the servo is detached when the minimum position
is reached. The servo is no longer driven. This is useful when the servo has
to push against an elastic restoring force. If false the servo continues to be
driven.
setDetachAtMax(detach)
detach is a boolean. If true, the servo is detached when the maximum position
is reached. The servo is no longer driven. This is useful when the servo has
to push against an elastic restoring force. If false the servo continues to be
driven.
setDetach(detach)
detach is a boolean. If true, the servo is detached when the minimum or the
maximum positions
are reached. The servo is no longer driven. This is useful when the servo has
to push against an elastic restoring force. If false the servo continues to be
driven.
isStopped()
Returns true if the servo is stopped.
pin()
Returns a byte which is the number of the pin. 255 is returned if the object
has not been connected to any pin.
detachAtMin()
Returns true if the servo is detached when reaching the minimum position.
detachAtMax()
Returns true if the servo is detached when reaching the maximum position.
minimumPulse()
Returns an uint16_t which is the pulse width in microseconds corresponding to the minimum servo position.
maximumPulse()
Returns an uint16_t which is the pulse width in microseconds corresponding to the maximum servo position.
minToMaxSpeed()
Returns a float which is the speed of the servo when traveling from minimum to maximum position.
maxToMinSpeed()
Returns a float which is the speed of the servo when traveling from maximum to minimum position.
isReverted()
Returns true if the movement is reverted.
position()
Returns the current position in float, from 0.0 to 1.0.
SlowMotionServo::setDelayUntilStop(delay)
This class function set the delay between the time the servos reach their
minimum or maximum
position and the the time they are detached. Because the mechanic is always
late
compared to the program, detaching immediately the servos would prevent them
to reach their mechanical position. This is set once for all the servos and
used only for servos and positions for which setDetach(true) is specified.
SlowMotionServo::update()
Update the positions of all the servos. This class function has to be called
in loop() as frequently as possible.
Live adjustement of minimum and maximum position
With version 1.1, 5 functions have been added to implement live adjustement of minimum and maximum positions. When an adjustement of a servo is in progress, the goTo, goToMin and goToMax functions fail silently.
Entering in live adjustement process is done implicitely by calling one of the for adjust functions. Exiting the live adjustement process is done by calling de endSetup() function.
setupMin(minPulse)
setupMin() sets the minimum pulse value. minPulse is an unsigned 16 bits integer. The servo enters in the live adjustement process: its state is saved, the minimum pulse is set to minPulse and it goes to the new minimum position so that the user can see it. If minPulse is greater than the maximum pulse, it is set back to the maximum pulse. If minPulse is lower than the minimum possible value of the Servo library (544), it is set back to the minimum possible value.
setupMax(maxPulse)
setupMax() sets the maximum pulse value. maxPulse is an unsigned 16 bits integer. The servo enters in the live adjustement process: its state is saved, the maximum pulse is set to maxPulse and it goes to the new maximum position so that the user can see it. If maxPulse is lower than the minimum pulse, it is set back to the minimum pulse. If maxPulse is greater than the maximum possible value of the Servo library (2400), it is set back to the maximum possible value.
adjustMin(increment)
adjustMin() adds increment to the minimum position. increment is a signed 16 bits integer. The servo enters in the live adjustement process: its state is saved, increment is added to the minimum pulse and it goes to the new minimum position so that the user can see it. If after adding increment, the minimum pulse is greater than the maximum pulse, it is set back to the maximum pulse. If after adding increment, the minimum pulse is lower than the minimum possible value of the Servo library (544), it is set back to the minimum possible value.
adjustMax(increment)
adjustMax() adds increment to the maximum position. increment is a signed 16 bits integer. The servo enters in the live adjustement process: its state is saved, increment is added to the maximum pulse and it goes to the new maximum position so that the user can see it. If after adding increment, the maximum pulse is lower than the minimum pulse, it is set back to the minimum pulse. If after adding increment, the maximum pulse is greater than the maximum possible value of the Servo library (2400), it is set back to the maximum possible value.
endSetup()
After calling the 4 previous function, endSetup() shall be called to exit the adjustement process. The state of the servo is restored. However it does not returns to the position it was before the adjustement process.
Example
Let’s drive a single servo with a smooth movement forward and backward.
First, include the libraries:
#include <Servo.h>
#include <SlowMotionServo.h>
Second, instantiate an object and a float to hold the target position:
SMSSmooth myServo; /* Servo with linear trajectory */
float target = 0.0;
Third, initialize it in setup(). Be careful actual minimum and maximum
positions of a servo may be greater and/or lower than positions allowed by
the Servo and SlowMotionServo libraries:
void setup()
{
myServo.setInitialPosition(target);
myServo.setMinMax(700, 2000);
myServo.setPin(3); /* the servo is connected to pin 3 */
}
Fourth, if the servo is stopped compute the new target position by doing
the subtraction 1.0 – target so that if target is 0.0, the new target is
1.0 and if target is 1.0 the new target is 0.0. And of course call update.
#include <Servo.h>
#include <SlowMotionServo.h>
SMSSmooth myServo; /* Servo with linear trajectory */
float target = 0.0;
void setup() {
myServo.setInitialPosition(target);
myServo.setMinMax(700, 2000);
myServo.setPin(3); /* the servo is connected to pin 3 */
}
void loop() {
if (myServo.isStopped()) {
target = 1.0 - target;
myServo.goTo(target);
}
SlowMotionServo::update();
}
How to define your own trajectory.
To do that, you have to inherit from the SlowMotionServo class and redefine
the slopeUp and slopeDown member functions. Let’s take the
SMSSmooth class as example:
Because trajectories are the same from min to max and max to min, we define
a new member function, slope, that defines the trajectory. This function is
called by slopeUp and slopeDown:
The Snake Activation Function [1] is a novel activation function for neural networks, designed to introduce non-linearity and enhance the model’s representational power. This README provides an overview of the PyTorch implementation of the Snake Activation Function.
Features
Learnable and Unlearnable Options: The Snake Activation Function implementation offers both learnable and unlearnable options for $a$. This allows flexibility in choosing whether the parameters of the activation function should be updated during training or remain fixed.
Initialization for Snake: [1] suggests $0.2 \leq a \leq a_{max}$ for standard tasks such as image classification. However, for tasks with expected periodicity, larger $a$, usually from $5$ to $50$ tend to work well.
Learnable $a$ is a default setting: Learnable $a$ works better than constant $a$ in general .
Usage
To use the Snake Activation Function in your PyTorch project,
import the SnakeActivation class from snake.py:
For more details on the Snake Activation Function and its implementation, please refer to the snake.py file.
Variant: Flexible Snake
The original snake function has a single $a$. The function can be expanded by having $a$ per channel to allow different non-linearities for different channels, which can potentially lead to better performance.
For example, consider a 1D input tensor with dimensions $(\text{batch size}, \text{num channels}, \text{length}) = (b, c, l)$. The function can have $c$ instances of $a$. For 2D input tensor with dimensions $(\text{batch size}, \text{num channels}, \text{height}, \text{width}) = (b, c, h, w)$, it’s the same, i.e., $c$ instances of $a$.
Examples:
fromsnakeimportFlexibleSnakeActivation# Example for 1D input with dimensions (batch_size, n_channels, length)classNet1D(nn.Module):
def__init__(self):
super(Net1D, self).__init__()
self.conv1=nn.Conv1d(3, 16, kernel_size=3, stride=1, padding=1)
self.snake=FlexibleSnakeActivation(16, dim=1)
self.conv2=nn.Conv1d(16, 16, kernel_size=3, stride=1, padding=1)
defforward(self, x):
""" x: (b c l) """x=self.snake(self.conv1(x))
x=self.conv2(x)
returnx# Example for 2D input with dimensions (batch_size, n_channels, height, width)classNet2D(nn.Module):
def__init__(self):
super(Net2D, self).__init__()
self.conv1=nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)
self.snake=FlexibleSnakeActivation(16, dim=2)
self.conv2=nn.Conv2d(16, 16, kernel_size=3, stride=1, padding=1)
defforward(self, x):
""" x: (b c h w) """x=self.snake(self.conv1(x))
x=self.conv2(x)
returnxmodel_1d=Net1D()
model_2d=Net2D()
x_1d=torch.rand(4, 3, 100)
out=model_1d(x) # (4 16 100)x_2d=torch.rand(4, 3, 32, 32)
out=model_2d(x) # (4 16 32 32)
I found that FlexibleSnakeActivation generally results in better performance than SnakeActivation.
Reference
[1] Ziyin, Liu, Tilman Hartwig, and Masahito Ueda. “Neural networks fail to learn periodic functions and how to fix it.” Advances in Neural Information Processing Systems 33 (2020): 1583-1594.
AutoPacker is an automated software packaging and deployment solution.
AutoPacker is a simple, but productive and transparent platform that is cloud-service and hosting independent and offers a way to manage projects, servers, deployment and storage, and being a platform for people to share projects and ideas.
AutoPacker was created by three bachelor students at NTNU as a part of their bachelor thesis project.
Contributing
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
Getting Started
AutoPacker consists of several modules, each is a separate sub-project:
File delivery API – manages projects, modules, dockerfiles and docker-compose blocks.
General API – REST API for organizations, supported languages and their versions
Server manager – manages user-owned servers, file upload to servers, etc.
User service – User management. Talks to a Keycloak service for authentication.
Except the Web application, all other sub-projects have a REST API interface. I.e., Web application is a REST client while all other modules are REST servers.
To run the system you need to run all these modules. See the “Installing” section for instructions.
Prerequisites
To develop the projects, you need the following services deployed somewhere:
The first section describes general requirements – for all the modules. The following sections describe setup steps
for each module of the project. Web application depends on all other modules.
General install instructions
All the server-side (backend) modules have two requirements which must be met:
A KeyCloak authentication server. This is needed to authorize users. You can set up your own KeyCloak server. If you want to use a predefined KeyCloak server for testing, take contact with AutoPacker developers.
Each module (file delivery, general API, server manager, and user service) use a MySQL for data storage. You must provide a database for each module. It is up to you to choose either to have a single shared DB for all the projects, or to have a separate DB for each project. The important thing is that you must provide a MySQL database – just an empty database, the modules will set up necessary tables. You can choose whether to run a MySQL container in a Docker container, have a Local MySQL installation, or use a remote MySQL database. The modules need only to have a URL to a MySQL server, database name, user and password.
Running User Service
To run the User Service:
Set up a MySQL database.
Create application.yml file in the src/main/resouces directory (take a copy of the template.application.yml file, fill in the values according to your implementation).
Run the project with either mvn spring-boot:run in the terminal, or launch the UserServiceApplication class from your IDE.
Running File Delivery API
File Delivery API has one extra requirement: a MongoDB database. Steps for running File Delivery API:
Set up a MongoDB database.
Set up a MySQL database.
Create application.properties file in the src/main/resouces directory (take a copy of the template.application.properties file, fill in the values according to your implementation). In case if you want to run different setups for development and production environments, you can create several property files, for example, application-dev.properties. Then you need to add a switch for the maven command when running it: -Dspring-boot.run.profiles=dev.
Create application.yml file in the src/main/resouces directory (take a copy of the template.application.yml file, fill in the values according to your implementation).
Run the project with either mvn spring-boot:run in the terminal, or launch the FileDeliveryApiApplication class from your IDE. If you use specific application.properties files, for example, application-dev.properties, you can specify which .properties configuration to use, for example: mvn spring-boot:run -Dspring-boot.run.profiles=dev will use application-dev.properties.
Running Server Manager
To run the User Service:
Set up a MySQL database.
Create application.yml file in the src/main/resouces directory (take a copy of the template.application.yml file, fill in the values according to your implementation).
Run the project with either mvn spring-boot:run in the terminal, or launch the ServerManagerApplication class from your IDE.
Running Web application
The web module is a React application. You need to install the dependencies (Javascript libraries) for the project first: run yarn install in the project directory.
To run a debug-version (during development), run yarn start in the project directory.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
Run yarn build to get a minified production-ready version of the site, it will be stored in the build directory.
Alternative to service application.yml configuration
We have created a docker image called autopacker/local-config-server that will distribute application.yml properties to the backend services without needing specify the values yourself. The only requirement to use this option is that the mysql database username is root and the password is left empty. The Mongo database also has the username root, but the password here is: password.
Docker environment setup (easy way)
If you are using docker you can easily setup the whole working environment with four steps. If you copy paste all the code lines below you should have a fully working development environment running on your machine!
Run keycloak server
We have created a local development keycloak server that can be run with:
docker container run -d --name keycloak -p 8080:8080 autopacker/local-keycloak
This will setup a local keycloak server on your host computer with the admin credentials (username: admin, password: admin). It also holds an example user (username: user, password: user)
Run Mysql container
Just creating a mysql container with a desired database set as environment property:
Using this pre-created local config server you don’t have to specify any properties unless you use custom values deviating from the database credentials mentioned further up. The config server is run with:
docker container run -d --name config-server -p 8888:8888 autopacker/local-config-server
Backend Services
When you have the four containers (MySQL, Mongo, Keycloak, Config Server) up and running you should be ready to start developing. Just run the backend services and they should be able to connect to the other services without any problems
Running the tests
TODO – Explain how to run the automated tests for this system
Deployment
TODO Add additional notes about how to deploy this on a live system.
Authors
Aron Mar Nicholasson
Liban Bashir Nor
Bendik Uglem Nogva
Girts Strazdins
See also the list of contributors who participated in this project.
License
This project is licensed under the MIT License – see the LICENSE file for details
Development of this app has been halted in favor of Agoras
🎒 Prep Work
Create an app with the twitter account where you want to share the tweets (https://developer.twitter.com/apps). You might need to fill an application form before being able to create an app. More info here.
Upload your images to a public access URL.
🖥 Workflow Usage
Configure your workflow to use LuisAlejandro/send-tweet-with-media@0.2.0,
and provide the tweet you want to send as the STATUS_TEXT env variable.
You can add up to 4 images as URLs in STATUS_IMAGE_URL_1, STATUS_IMAGE_URL_2, STATUS_IMAGE_URL_3 and STATUS_IMAGE_URL_4
env variables. The script will download and attach them to the tweet.
You can omit all 4 variables and no image will be attached.
Provide the authentication keys and tokens for your Twitter app
as the TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, TWITTER_OAUTH_TOKEN, and TWITTER_OAUTH_SECRET env variables
(as secrets). Remember, to add secrets go to your repository Settings > Secrets > Actions > New repository secret
for each secret.
For example, create a file .github/workflows/push.yml on
a github repository with the following content:
Flood is a monitoring service for rTorrent. It’s a Node.js service that communicates with rTorrent instances and serves a decent web UI for administration. It’s a work-in-progress.
Feedback
If you have a specific issue or bug, please file a Github issue. Please join the Flood Discord server to discuss feature requests and implementation details.
Getting started
Pre-Requisites
rTorrent needs to be installed and running with XMLRPC configuration.
Copy config.template.js to config.js and review its comments. This is required.
When loading the web interface, you will be prompted to configure the connection to rtorrent. Other configuration options are handled config.js.
What to configure
Be sure to create a long and unique secret (used to sign JWT auth tokens).
If you are proxying requests to Flood from your own web server, configure Flood’s path from the host at the baseURI property. All requests will be prefixed with this value.
For example, if serving Flood from https://foo.bar/apps/flood, you would set baseURI to /apps/flood. If serving flood from https://foo.bar, you do not need to configure baseURI.
Note: Some of these values are baked into the static assets (like baseURI), so changes to this file require recompling static assets.
Compiling assets and starting the server
From the root of the Flood directory…
Run npm install if you haven’t already or if you’ve pulled changes.
Run npm run build.
Run npm start.
Access the UI in your browser. With default settings, go to http://localhost:3000. You can configure the port in config.js.
Updating
I’ve been bad about cutting actual releases, so check this repo for recent commits.
To update, run git pull in this repository’s directory.
Check config.template.js for configuration changes that you may wish to incoporate in your config.js.
Kill the currently running Flood server.
Run npm install to update dependencies.
Run npm run build to transpile and bundle static assets.
Start the Flood server with npm start.
Troubleshooting
Ubuntu users may need to install nodejs-legacy (sudo apt-get install nodejs-legacy) for dependencies to install successfully. You can read more on this Stack Overflow post.
Run npm run start:development:server and npm run start:development:client in separate terminal instances.
npm run start:development:server uses nodemon to watch for changes to the server-side JavaScript.
npm run start:development:client watches for changes in the client-side source.
Access the UI in your browser. Defaults to localhost:4200.
Environment Variables
DEV_SERVER_PORT: webpackDevServer’s port, used when developing Flood. Defaults to 4200.
DEV_SERVER_HOST: webpackDevServer’s host, used when developing Flood. Defaults to 0.0.0.0.
DEV_SERVER_HTTPS: webpackDevServer’s protocol, used when developing Flood. Defaults to http.
Running with Docker
docker build -t rtorrent-flood .
docker run --name rtorrent-flood -e RTORRENT_SCGI_HOST=w.x.y.z -p 3000:3000 rtorrent-flood
Other supported environment variables:
FLOOD_BASE_URI
FLOOD_SECRET
FLOOD_ENABLE_SSL
The docker container includes a volume at /data, which is where the database will be located. Additionally, you can place your SSL files there, /data/flood_ssl.key and /data/flood_ssl.cert. Set FLOOD_ENABLE_SSL to true to enable their use if present. Additionally, a local rtorrent socket file located at /data/rtorrent.sock can be used if RTORRENT_SOCK is set to true. The location of the socket file can be overrided by setting RTORRENT_SOCK_PATH to the path of the socket.
Allows dog owners to connect and schedule time to take their dogs to go to parks and meet up for play dates.
App Evaluation
Category: Social, Lifestyle
Mobile: GPS, Camera
Story: Creates connections between dog owners. Allows for dogs and their owners to meet and have fun social interactions safely, with other dogs that match well in the same area.
Market: Dog owners who want to socialize over their pets.
Habit: Dog owners can be notified a few times a week to take their dogs out for longer trips / to parks to socialize. User can be more engaged if there is a timeline to add pictures.
Scope: MVP would consist of:
User able to build profiles for dogs
User would be able to find profiles of other dogs nearby
User would be able to schedule with / message other dog owners
(Opt) Timeline
Product Spec
1. User Stories (Required and Optional)
Required Must-have Stories
User can create an account and login
User can view their own profile
User can create profiles for each of their dogs attached to their account
User can see locations of other dog owners
User can use their GPS location to explore the local area and find other dog owners
User can view local dog owner profiles
User can send messages to other dog owners and schedule playdates
Optional Nice-to-have Stories
User can also find nearby parks in the explore screen
User can post pictures to their dog’s timeline and engage with other dogs’ timelines
User can receive push notifications a few times a week to take their dogs for longer walks / trips to a park to socialize.
2. Screen Archetypes
Launch screen
This screen welcomes the user when opening the app for the first time.
Login screen
If user has an account, this screen allows for logging in.
(Opt) If the user has logged into an account previously, this screen is opened upon launch.
Register screen
If user does not have an account, this screen allows for creating one.
Messaging screen
This screen allows the user to communicate with other users (1-on-1).
User (owner) profile screen
This screen shows the user profile picture and the user’s pets.
Pet profile screen
This screen shows the pet profile picture and profile details.
Explore screen
This screen shows a map of the local area and pins for locations of parks, landmarks, and nearby pets.
(Opt) Timeline screen
This screen can show recent posts added in the local area.
3. Navigation
Tab Navigation (Tab to Screen)
(Opt) Timeline
Explore
Profile
Messaging
Flow Navigation (Screen to Screen)
Launch screen ->
Create account -> Profile
Log in -> Profile
(Opt) Timeline ->
Post details -> Post user’s profile
Post user’s profile
Explore
Profile ->
Add/edit pet
Pet profile
Messaging -> Message detail
Wireframes
[BONUS] Digital Wireframes & Mockups
[BONUS] Interactive Prototype
Schema
Models
User
Property
Type
Description
objectId
String
unique id for the user (default)
email
String
user email
password
String
user password
username
String
user username / display name
createdAt
DateTime
date when the post is created (default)
friends
Array (of Pointer to User)
list of friends of user
profileImage
File
profile image url
createdAt
DateTime
date when the user profile is created (default)
updatedAt
DateTime
date when the user was last updated (default)
Pet
Property
Type
Description
objectId
String
unique id for the pet (default)
owner
Pointer to User
pet owner
name
String
pet name
breed
String
pet breed
age
String
pet age
gender
String
pet gender
bio
String
description about pet
petImage
File
pet profile image url
createdAt
DateTime
date when the pet profile is created (default)
updatedAt
DateTime
date when the pet is last updated (default)
Post
Property
Type
Description
objectId
String
unique id for the post (default)
author
Pointer to User
image author
pets
Array (of Pointer to Pet)
list of pets in image tagged by author
image
File
image that user posts
caption
String
image caption by author
commentCount
Number
number of comments on the post
likeCount
Number
number of likes for the post
createdAt
DateTime
date when the post is created (default)
updatedAt
DateTime
date when the post is last updated (default)
Comment
Property
Type
Description
objectId
String
unique id for the post (default)
author
Pointer to User
comment author
post
Pointer to Post
post that comment refers to
parentId
Pointer to Comment
unique id of the parent comment
text
String
the comment’s text
likeCount
Number
number of likes for the post
createdAt
DateTime
date when the comment is created (default)
updatedAt
DateTime
date when the comment is last updated (default)
Message
Property
Type
Description
objectId
String
unique id for the message (default)
author
Pointer to User
message author
recipient
Pointer to User
message recipient
text
String
the message’s contents
createdAt
DateTime
date when the message is created (default)
updatedAt
DateTime
date when the message is last updated (default)
Networking
List of network requests by screen
Launch screen
Login screen
Register screen
(Create/POST) Create a new user
Messaging screen
(Create/POST) Create a new message thread
(Read/GET) Query all message threads where user is an author or recipient
(Delete) Delete a message thread
Message detail screen
(Create/POST) Create a new message
(Read/GET) Query all messages in thread
(Update/PUT) Update an existing message
(Delete) Delete an existing message
User (owner) profile screen
(Create/POST) Add a new pet
(Read/GET) Query all pets where user is owner
(Update/PUT) Update user details
(Delete) Delete an existing pet
Pet profile screen
(Create/POST) Create a new post (pet tagged automatically?)
(Read/GET) Query all posts where pet is tagged
(Update/PUT) Update/edit existing post where user is author
Rush Hour is a sliding block logic game, which is considered as one of the best logic games of all time where you have to escape the biggest boss… Traffic!
How to play
Try to lead the red car to the exit by moving the other vehicles on the map out of the way.
At the end of each level, you collect stars according to how well did you do in that level.
The Less moves you make the more stars you collect.
Use your stars to uunlock new and awesome themes.
You can use 2 Power-ups for help if you are stuck.
Poof: Select an obstacle to make it disappear.
Shrink: Select a 3 by 1 object to make it a 2 by 1 object.
Notes
Rush Hour is a term project made by a group of 3 for our Object Oriented Programming Course.
Everything is written in Java from scratch except for the gson and the java swing libraries.
There is no game engine involved, the game loop is designed and written by us.
All visual assets are either found or drawn by me personally.